fscanf () только подбирает первую строку файла

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

#include  #include  #define SELLERCODE A2LQ9QFN82X636 int main () { typedef char* string; FILE* stream; FILE* output; string asin[200]; string sku[15]; string fnsku[15]; int quality = 0; stream = fopen("c:\\out\\a.txt", "r"); output = fopen("c:\\out\\output.txt", "w"); if (stream == NULL) { perror("open"); return 0; } for(;;) { fscanf(stream, "%[^\t]\t%[^\t]", sku, fnsku); printf("%s\t%s\n", sku, fnsku); fprintf(output, "%s\t%s\t%\t%s\t%s\t%i\n", sku, fnsku, asin, quality); } } 

    Предпочитают fgets() читать входные данные и анализировать строки в вашей программе, используя, например, sscanf() или strtok() .

    fscanf как известно, трудно использовать.
    Ваш fscanf не выполняет никаких преобразований после первой строки.
    Он считывает символы до TAB , затем игнорирует TAB и читает больше символов до следующей TAB . Во второй раз через цикл нет данных для sku : 1-й символ – TAB .

    Однако проверьте возвращаемое значение . Это очень помогает.

     chk = fscanf(stream, "%[^\t]\t%[^\t]", sku, fnsku); /* 2 conversions: sku and fnsku */ if (chk != 2) { /* something went wrong */ } 

    Вы читаете

      fscanf(stream, "%[^\t]\t%[^\t]", sku, fnsku); 

    После чтения первой строки, которая должна заканчиваться символом табуляции (как в "%[^\t]\t%[^\t]" ). Входной буфер имеет последний символ табуляции ‘\ t’, который не считывается вышеупомянутым вызовом функции. Поэтому в следующей итерации он начинается с вашей строки формата. Но fcanf в следующей итерации сразу возвращается, так как в самом начале столкнулся символ «\ t» ( "%[^\t]" ), поэтому буферы по-прежнему имеют последнее значение чтения. Начиная с этого fscanf каждая итерация пытается прочитать файл с fscanf но с ошибкой каждый раз сталкивается с '\t' в самом начале. Таким образом, вы не читаете этот файл, и первые прочитанные значения из ваших программных буферов отображаются снова и снова.

    Вам необходимо прочитать последний символ, который завершил сопоставление сканирования. Вы можете использовать fgetc (stream) после fscanf () или использовать следующую строку формата: "%[^\t]\t%[^\t]%*c" . %*c – синтаксис подавления присваивания. Это приведет к тому, что один символ будет прочитан из входного файла, но затем отбросит его.

    Также вы должны проверить, что возвращает fscanf () . Если он не возвращает 2 (количество прочитанных элементов), тогда возникает проблема, с которой вы должны справиться. Таким образом, вы можете гарантировать, что правильное количество элементов было прочитано при одном вызове.

    Так или вы можете сделать:

      while (!feof (stream)) { fscanf(stream, "%[^\t]\t%[^\t]", sku, fnsku); fgetc (stream); printf("%s\t%s\n", sku, fnsku); fprintf(output, "%s\t%s\t%\t%s\t%s\t%i\n", sku, fnsku, asin, quality); } 

    Или вы можете сделать:

      while (!feof (stream)) { fscanf(stream, "%[^\t]\t%[^\t]%*c", sku, fnsku); printf("%s\t%s\n", sku, fnsku); fprintf(output, "%s\t%s\t%\t%s\t%s\t%i\n", sku, fnsku, asin, quality); } 

    Но я рекомендую прочитать его с помощью fgets () а затем проанализировать его внутри вашей программы с помощью strtok () или другими способами и способами.

    EDIT1:

    Обратите внимание, что если у вас есть исходный файл с символом '\n' то после чтения строк, как указано выше, в ваши буферы будет добавлена ​​дополнительная новая строка. Если вы все еще считаете, что непосредственно читаете поля с fscanf () где каждая строка имеет несколько полей, fscanf () '\t' и запись заканчивается символом '\n' вы должны использовать следующую строку формата: "%[^\t]\t%[^\t]\n" .

    Трудно ответить, пока мы не получаем точный формат файла. В файле содержится только одна строка с полями, разделенными вкладками? Или есть несколько строк, каждая строка имеет поля, разделенные вкладками. Если последнее верно, лучше всего просмотреть всю строку сразу, а затем проанализировать ее внутренне.

    Хорошо, вот что происходит на самом деле. Вы читаете первую строку, и с этого момента вы ничего не читаете и просто повторно используете эти значения. Вы должны проверить возвращаемое значение fscanf и выйти из цикла, если оно меньше двух (которое будет после первой итерации). Ваша строка fscanf должна выглядеть так:

     if( fscanf(stream, "%[^\t]\t%[^\t]\n", sku, fnsku) < 2 ) break; 

    Ключ - это новая строка в конце, которая будет использовать новую строку на вкладке.

    Есть проблемы с вашим printf. (Неправильное количество строк форматирования.) Я оставлю это вам.