Почему fscanf выдает ошибку сегментации при чтении данных в текстовый файл? - PullRequest
1 голос
/ 24 сентября 2019

Я пытаюсь прочитать данные из текстового файла с некоторыми данными в нем.


Мой текстовый файл:

1 dior Asfiya 20 abcde 12345
2 abde Sabah 17 saar 5757657

Мой код:

typedef long long int ulong;
struct Customer
{
    char name[25];
    int acc_no;
    int age;
    char gender[2];
    char address[60];
    ulong phone;
    char password[10];


};
struct Customer add,check;

int new_acc()
{
        int c;
        FILE *p;
        FILE *q;
        p = fopen("test.txt","a");
        q = fopen("test.txt","r");
        if(p == NULL)
        {
            puts("Could't open file\n");
            return(-1);
        }
        if(q == NULL)
        {
            puts("Couldn't open file\n");
            return(-1);
        }
        account_no:
        printf("\nAdd record");
        printf("\nEnter account number: ");
        scanf("%d",&check.acc_no);
        while(c = fscanf(q,"%d %s %s %d %s %s %llu%[^\n]",&add.acc_no,add.password,add.name,&add.age,add.gender,add.address,&add.phone) == 7)
        {
            if(check.acc_no==add.acc_no)
            {
                printf("\nAccount no. already in use!");
                goto account_no;
            }
        }
        if(c != EOF){
            goto details;
        }
        details:
        add.acc_no = check.acc_no;
        printf("\nEnter password: ");
        scanf("%s",add.password);
        printf("\nFull Name: ");
        scanf("%s",add.name);
        printf("\nEnter your age: ");
        scanf("%d",&add.age);
        printf("\nEnter your gender: ");
        scanf(" %c",&add.gender);
        printf("\nEnter address: ");
        scanf("%s",add.address);
        printf("\nEnter phone number: ");
        scanf("%llu",&add.phone);
        fprintf(p,"%d %s %s %d %s %s %lld\n",add.acc_no,add.password,add.name,add.age,add.gender,add.address,add.phone);
        fclose(p);
        fclose(q);

}

При отладке кода возникает ошибка сегментации, когда начинается цикл , в то время как .Он прекрасно работал до добавления первой строки данных в файл.Я не могу понять, почему это происходит.

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019

Удалить goto.

Измените эту часть кода, пожалуйста.


О ваших массивах, которые ожидают сохранения строки - не так липринять во внимание строку NULL терминатора, которая также нуждается в ячейке массива для хранения?

В любом случае, я вижу, gender имеет размер 2, но ваш ввод предполагает, что ему нужно больше.

Ваш ввод имеет 7 токенов:

1 dior Asfiya 20 abcde 12345

, что означает, что gender переполнит , вызывая Undefined Behavior (UB) , так как вы попытаетесь сохранить строку длиной 4 символав массив размера 2. Это может объяснить сбой.

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

Вы, вероятно, имели в виду:

1 dior Asfiya 20 abcde f 12345


Изменить это:

while(c = fscanf(q,"%d %s %s %d %s %s %llu%[^\n]",&add.acc_no,add.password,add.name,&add.age,add.gender,add.address,&add.phone) == 7)

к этому:

while((c = fscanf(q,"%d %s %s %d %s %s %llu%[^\n]",&add.acc_no,add.password,add.name,&add.age,add.gender,add.address,&add.phone)) == 7)

, поскольку из-за приоритета операторов сравнение происходит за до назначения, что не то, что вам нужно.Сначала вы хотите присвоить свою переменную, а затем сравнить, поэтому используйте скобки, чтобы указать желаемый приоритет.

2 голосов
/ 24 сентября 2019

Вы неправильно устанавливаете c, когда пишете:

while(c = fscanf(q,"%d %s %s %d %s %s %llu%[^\n]",&add.acc_no,add.password,add.name,&add.age,add.gender,add.address,&add.phone) == 7)

Это установка c на результат сравнения ==, поскольку == имеет более высокий приоритет, чем =.

Кроме того, вам не нужно [^\n] в конце строки формата.%d в начале пропустит все пробелы, включая символ новой строки в конце предыдущей строки.

Это должно быть:

while((c = fscanf(q,"%d %s %s %d %s %s %llu",&add.acc_no,add.password,add.name,&add.age,add.gender,add.address,&add.phone)) == 7)

Я не уверен, что вы намереваетесьс

        if(c != EOF){
            goto details;
        }
        details:

Поскольку details: находится сразу после оператора if, вы идете туда независимо от того, выполнено ли условие.

Вы должны отказаться от привычки использовать goto это обычно считается плохим стилем программирования.Поместите код, который должен выполняться, когда условие истинно, внутри if.Вы можете использовать continue и break для перезапуска и завершения цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...