Fgets читает слишком много символов, чем существует - PullRequest
0 голосов
/ 22 августа 2010

У меня есть следующая функция:

void writeResults(FILE* fp, FILE* fpw, Vector w, int size) {

 Vector x;

 while (1) {

       char line[MAX_DIMENSION];  //max dimension is 200

       if( (fgets(line,MAX_DIMENSION,fp)) == NULL) { //EOF
            return;
       }
       else {
           int i=0;
           while (line[i]!='\0') {
                printf("% d %c\n",i,line[i]); //print to check it
                i++;
           }
       }
 }
}

Строка файла, который он читает:

1,1
2,2

Однако, когда я печатаю каждый символ до '\ 0', я получаю следующий вывод:

 0 1  
 1 ,  
 2 1  
 3   
 4   
 0 2  
 1 ,  
 2 2  
 3   
 4   

Кто-нибудь знает, почему он читает дополнительные 3 и 4 символа? (в файле нет лишних пробелов).

Примечание: файл был открыт следующим образом:

FILE* fp = fopen(fileIn, "r");
if (fp == NULL) {
    perror("Couldn't open File");
    exit(errno);
}

Ответы [ 3 ]

2 голосов
/ 22 августа 2010

не печатайте% c, печатайте% d, и вы увидите код символов ascii. Вы найдете символы возврата каретки и перевода строки. 13 и 10

см. http://www.asciitable.com/

1 голос
/ 22 августа 2010

Я думаю, что ваш входной файл содержит -

1,1
[SPACESPACE]
2,2
[SPACESPACE]

, поэтому первый раз fgets читается как -

line{'1',',','1','',''}

, а второй раз читает

line{'2',',','2','',''}

вот почему, вы получаете вывод, как вы указали

1 голос
/ 22 августа 2010

Возврат каретки, перевод строки - в Windows?

Было бы полезно, если бы мы знали, как вы открыли файл. Если вы открыли его в виде текстового файла, то вы не должны видеть два дополнительных символа - только один для новой строки. Однако, если вы откроете его как двоичный файл, он действительно должен прочитать и CR, и LF.

Если вы используете Linux, как указано в комментариях, у нас есть больше диагностических инструментов. Пожалуй, проще всего начать с 'od -c file'; это покажет вам, что именно в файле. Обратите внимание, что если файл когда-либо находился в окне Windows, он все равно мог иметь окончания строки CRLF Если вы используете 'vim', он может сказать, что тип файла - '[dos]'.

Кроме того, вы можете печатать символы в виде целых чисел (а также символов):

printf("%d (%2d) %c\n", i, line[i], line[i]);

Вы должны увидеть 49 для «1», 50 для «2», 44 для «,», 10 для новой строки (LF, «\n») и что-то еще - это загадка (но это будет показать 13 для CR).


CR - это символ \r в C-источнике. Он использовался для указания того, что печатающая головка должна вернуться в начало строки (каретка принтера вернулась в начало строки); LF или перевод строки прокручивали бумагу вверх по линии. Windows и MS-DOS используют последовательность CRLF (curr-liff) для обозначения конца строки; Unix всегда использовал только LF, aka newline или NL; MacOS 9 и более ранние версии использовали только CR.

...