c-fscanf()只获取文件的第一行



我有一个制表符分隔的文件,我正试图将其转换为制表符分隔文件。我在用C。我一直在读文件的第二行。现在我只有数以万计的行重复第一行。

#include <stdio.h>
#include <string.h>
#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("%st%sn",  sku, fnsku);
       fprintf(output, "%st%st%t%st%st%in", sku, fnsku, asin, quality);
     }
}

首选fgets()读取输入并解析程序中的行,例如使用sscanf()strtok()

fscanf是出了名的难以使用
您的fscanf在第一行之后没有执行任何转换
它读取一个TAB之前的字符,然后忽略TAB,并读取更多字符直到下一个TAB。在循环的第二次,sku没有数据:第一个字符是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读取文件,但每次在一开始遇到't'时都会失败。因此,您不会继续读取文件,并且程序缓冲区中的第一个读取值显示在上下

您需要读出终止扫描集匹配的最后一个字符。您可以在fscanf ()调用后使用fgetc (stream),也可以使用以下格式字符串:"%[^t]t%[^t]%*c"%*c是分配抑制语法。这将从输入文件中读取一个字符,但随后将其丢弃

此外,您还应该检查fscanf ()返回的内容。如果它没有返回2(要读取的元素数),那么就有一个问题需要处理。通过这种方式,您可以确保在一次调用中读取正确数量的元素。

所以你可以做:

 while (!feof (stream))
 {
   fscanf(stream, "%[^t]t%[^t]", sku, fnsku);
   fgetc (stream);
   printf("%st%sn",  sku, fnsku);
   fprintf(output, "%st%st%t%st%st%in", sku, fnsku, asin, quality);
 }

或者你可以做:

 while (!feof (stream))
 {
   fscanf(stream, "%[^t]t%[^t]%*c", sku, fnsku);
   printf("%st%sn",  sku, fnsku);
   fprintf(output, "%st%st%t%st%st%in", sku, fnsku, asin, quality);
 }

但我建议用fgets ()阅读它,然后用strtok ()或其他方法在程序中解析它。

第1版:

请注意,如果原始文件以'n'结尾,那么在如上所述读取行之后,将在缓冲区中添加一个额外的换行符。如果您仍然考虑使用fscanf ()直接读取字段,其中每行有多个用't'分隔的字段,并且一个条目以'n'终止,那么您应该使用以下格式字符串:"%[^t]t%[^t]n"

当我们没有得到文件的确切格式时,很难回答。文件是否只包含一行,字段用制表符分隔?或者有多行,每行都有制表符分隔的字段。如果后面的情况是真的,最好是一次扫描整行,然后在内部进行解析。

好的,这是实际发生的事情。你正在阅读第一行,从那时起,你什么都不读,只是重复使用这些值。您应该检查fscanf的返回值,如果它小于2(将在第一次迭代后),则退出循环。你的fscanf行应该是这样的:

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

关键是末尾的换行符,它将吃掉输入中的换行符。

你的printf也有一些问题。(格式化字符串的数目不正确。)我把这个留给你。

相关内容

  • 没有找到相关文章

最新更新