Использование strtok () вместе с fgets () приводит к segfault, но указатели должны быть правильными - PullRequest
1 голос
/ 04 декабря 2011

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

Вот код:

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

int main()
{
   FILE *file = fopen("listing.txt","r"), *output;

   char *fvar;
   char *svar;
   char delim[] = ",";
   int num;
   char ch;
   char line[66];
   int listnum = 0;

   if(file == NULL){
        printf("Cannot open file.\n");
        exit(1);
   }

   output = fopen("report.txt","w");

   fprintf(output, "%s", "First Name     Last Name     Number ");
   fprintf(output, "%s", "-------------------------------------");

   while(fgets(line, 66, file) != NULL){
       ch = line[0];
       if((ch >= 'a') && (ch <= 'z')){
           fvar = strtok(line,delim);
           svar = strtok(NULL,delim);
           listnum++;
       }
       else {
            num = atoi(line);
       }
       fprintf(output, "%s", fvar);
       fprintf(output, "%15s", svar);
       fprintf(output, "%30d", num);
       fprintf(output, "%56s", "\n");
   }
   fclose(file); /* done reading from the input file */
   fclose(output); /* done writing the the output file */
   return 0;
}

То, что я пытаюсь сделать, это прочитать строкутекстовый файл.Если строка содержит информацию в виде «строка, строка», то токенизируйте оба из них и сохраните их в fvar и svar соответственно.Если это числовая строка, используйте atoi (), чтобы получить значение и сохранить его в num.

По какой-то причине это вызывает ошибку segfault, хотя она компилируется нормально.Я почти уверен, что проблема в строках fvar = strtok(temp,delim); и svar = strtok(NULL,delim);, но я не знаю, как это исправить.Примечание: то же самое происходит, если я использую fvar = strtok(line,delim);.

Редактировать : исправлено, спасибо @Chris Dodd.По собственному желанию я пойду за учебником первого класса и снова изучу алфавит.

Ответы [ 2 ]

2 голосов
/ 04 декабря 2011

Скорее всего, проблема в том, что ваша первая строка ввода не начинается со строчной буквы, поэтому вы никогда не вызываете strtok в первую очередь и никогда не присваиваете svar или fvar, но вы все равно передаете эти (неинициализированные) значения в printf, который затем дает ошибку по умолчанию ...

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

0 голосов
/ 04 декабря 2011

strtok может вернуть NULL.Если вы игнорируете эту возможность, нарушения доступа легко вызвать.всегда проверяйте состояние возврата функции, которую вы вызываете.

fvar = strtok(temp, delim); 
if (fvar != NULL) 
{
    printf("%s\n", fvar);
    svar = strtok(NULL, delim);
    if (svar != NULL)
    {
        printf("%s\n", svar);
    }
    else
    {
        /* illegal to access contents of svar */
    } 
 } 
 else 
 {
     /* illegal to access contents of fvar */ 
 }

/ *, не связанной с вопросом, может оказаться полезным включить файл включения ctype.h, поскольку он предоставляет семейство функций вида.. toupper, isletter, isdigit и тому подобное * /

...