Вопрос по fread, file-io, compiler-errors, c – Что не так с фредом в этой программе?

1

Я учусь на среднем C. Я пытаюсь создать программу управления банком, но сначала мне нужно создать программу входа в систему, поэтому я создал одну из следующих. Как я недавно узнал о файловом вводе / выводе в C, я не очень разбираюсь в fread и fwrite. У меня есть файл (data.txt), формат которого, как показано ниже.

user1 1124

user2 3215

user3 5431

В следующей программе я попросил пользователя ввести имя пользователя и пин-код (4-значный пароль) и скопировать данные файла в структуру, а затем сравнить эти два для проверки информации.

Что не так с моей программой и как заставить фред работать правильно. И форматирование в файле data.txt все в порядке, или я должен изменить его.

Заранее спасибо...

#include<stdio.h>
#include<ctype.h>
#include<string.h>

struct user_account    {
    char u_name[30];
    int u_pin;
} log_in;



    int login()
{
    int start;
    int i, n;
    int t_pin[4];       // TEMPORARY INT PIN for storing pin inputed by user
    char t_name[30];    //  TEMPORARY STRING for storing name inputed by user

    FILE *fp;
    fp = fopen("data.txt","rb");        // Opening record file

    if(fp == NULL)
    {
    puts("Unable to open file!");
    return 1;
    }

    start :  {
        printf("User Name : ");
        scanf("%s",&t_name);
        printf("Pin Code  : ");

        for(i = 0; i < 4; i++)  {       // This loop is for hiding input pin
            n = getch();

            if(isdigit(n))  {
                t_pin[i] = n;
                printf("*");    }
            else    {
                printf("\b");
                i--;
            }
        }

        fread(&log_in,sizeof(log_in),1,fp);

        // Comparing user name and pin with info in the structure copied from the file

        if(strcmp(log_in.u_name, t_name) == 0 && log_in.u_pin == t_pin)
            puts("Login successful! Welcome User");
        else    {
            printf("\nIncorrect Information!\n");
            printf("Press any key to log in again...");
            getch();
            system("cls");
            goto start; }
        }
    }

    int main()
    {
    int login();
        return 0;
    }
Вам нужно предоставить немного больше информации. В чем проблема? Ваш код не компилируется? Если это так, укажите ошибку компилятора. Он компилируется, но не делает то, что вы хотите? Если так, то скажите нам, что вы хотите, чтобы он делал, и что он делает вместо этого. wolfPack88
Ну, я хочу, чтобы он скопировал эти данные файла в структуру, и я хочу сравнить имя пользователя и пин-код, предоставленные пользователем, со структурой. Если это совпадает с любым пользователем в структуре. Это пойдет вперед или же даст пользователю еще одну попытку. Но когда я запускаю эту программу, она возвращает 1 с пустым экраном, ничего не появляется. Mirwise Khan

Ваш Ответ

3   ответа
3

что у вас есть ASCII / текстовый файл, но вы пытаетесь использоватьfread читать прямо в структуру; для этого требуется файл в двоичном формате.fread не может сделать преобразование формата. использованиеfscanf вместо:

fscanf(fp, "%s %d", &log_in.u_name, &log_in.u_pin);
Чтобы написать бинарный файл, совместимый с вашимfread, вам в основном нужно заполнить структуру, а затемfwrite Это.fread/fwrite ничего не делает, кроме передачи указанного количества байтов между файлом и памятью, без преобразования. Кроме того, обратите внимание, что это проблематично, если вы переносите файл между двумя разными машинами с обратным порядком байтов (Google для «endian»). DoxyLover
Спасибо! Какой файл лучше всего подходит для fread (двоичный файл) и в каком формате мне следует записывать данные в этот файл. Как я должен сканировать вторую и третью строку в файле, используя fscanf. И как мне сканировать, если в файле n строк и я хочу сравнить имя пользователя и пин-код со всем файлом. Mirwise Khan
0

тах). Хотя это вариант, вы можете обнаружить, что fscanf больше подходит для вашего случая использования.

b) goto, возможно, имеет свои применения, но в вашем конкретном случае цикл while гораздо более уместен, поскольку он делает намерение более ясным и менее подверженным неправильному использованию.

в) Суть вашей проблемы - чтение файла. Вы только читаете и проверяете только одну запись из вашего файла за проход, и как только все записи прочитаны, вы получите EOF, а не дополнительные записи.

У вас есть несколько вариантов. Вы можете прочитать всю пользовательскую таблицу в список до цикла входа в систему. Когда пользователь входит в систему, вы должны перебирать список, пока не будет найдено совпадение или конец списка. В качестве альтернативы вы можете перебирать весь файл при каждой попытке пользователя найти совпадение и вернуться к началу файла, когда вы закончите. В любом случае вы должны проверить и обработать ошибки чтения.

d) Наконец, когда введена нецифровая цифра, вы, вероятно, обнаружите, что возврат не является тем, что вы имели в виду. Также вы можете подумать о том, чтобы позволить пользователю нажимать клавишу Backspace при вводе пин-кода.

Спасибо! Можете ли вы предоставить прототип цикла log_in с использованием fscanf? в этом цикле, как мне сказать fscanf перейти на другую строку и посмотреть, соответствует ли имя пользователя и пин-код этой записи. Наконец, пожалуйста, предоставьте мне прототип пин-кодирования, как вы упомянули в своем пункте ответа (d). Mirwise Khan
1

Следующая строка неверна.

scanf("%s",&t_name);

Вам необходимо использовать:

scanf("%29s",t_name);

fread не является правильным решением, учитывая формат файла.fread работает, когда файл в двоичном формате.

Учитывая формат вашего входного файла, вам необходимо использовать:

 scanf("%29s %d", log_in.uname, &log_in.u_pin); 

Сравнивая контакты с помощьюlog_in.u_pin == t_pin должен выдать ошибку компилятора. Типlog_in.u_pin являетсяint в то время как типt_pin являетсяint [4], Вам придется изменить свою стратегию для получения целочисленного значения отt_pin.

Вы можете использовать что-то вроде:

int pin = 0; 
for (i = 0; i < 4; ++i )
{
   pin = 10*pin + t_pin[i];
}

Однако, чтобы это работало, вы должны хранить правильные целочисленные значения вt_pin, Когда персонаж, который вы читаете'1', ты должен хранить1, Либо так, либо вам придется изменить вышеприведенный цикл for на:

   pin = 10*pin + t_pin[i]-'0';

Способ использованияgoto start цикл в вашей функции не является правильным. Вы не прочитали все идентификаторы и контакты пользователя из входного файла и сравнили их. То, как у вас это получится, в итоге вы сделаете:

Прочитайте имя пользователя и пин-код

Сверьтесь с первой записью в файле. Если они не совпадают ...

Прочитайте имя пользователя и введите еще раз.

Сверьтесь со следующей записью в файле. Если они не совпадают ...

и т.п.

Вы хотите:

Прочитайте имя пользователя и пин-код

Сверьтесь с первой записью в файле. Если они не совпадают ...

Сверьтесь со следующей записью в файле. Если они не совпадают ...Сверьтесь со следующей записью в файле. Если они не совпадают ...

и т.п.

Сchar u_name[30];, следует использоватьscanf("%29s%d", log_in.uname, &log_in.u_pin);. "29" это максимальная ширинаchar сканировать вlog_in.uname, Затем'\0' добавлен вlog_in.uname, +1 за лучший ответ. chux
@MirwiseKhan, это последнее. R Sahu
@ chux, спасибо за зоркие глаза и дайте мне знать :) R Sahu
Этоscanf("%29s%d", &log_in.u_name, &log_in.u_pin); ? или жеscanf("%29s%d", log_in.uname, &log_in.u_pin); Mirwise Khan

Похожие вопросы