在 C 中读取文件:前导零

reading a file in C: leading zeros

在我的程序中,我试图从文本文件中每行读取两个值。 它适用于我下面的代码,但是当我面对带有前导零的数字时,它会将每个零存储为一个值。

我希望能够阅读例如"007" 像普通的 "7",但我仍然希望能够读取 "0"[=33] =] 作为一个值。

任何人都可以帮助我改进我的代码或指出 what/where 它可以改进吗?

提前致谢

valuelist.txt

55 009
63 10
12 0

输出

counter: 0 | Value A: 55 Value B: 0 
counter: 1 | Value A: 9 Value B: 0 
counter: 2 | Value A: 9 Value B: 0 
counter: 3 | Value A: 63 Value B: 0 
counter: 4 | Value A: 10 Value B: 0 
counter: 5 | Value A: 12 Value B: 0 
counter: 6 | Value A: 0 Value B: 0 

主要

int main(void) {

        char name[] = "valuelist.txt";
        unsigned int counter = 0;
        unsigned int lines = 3;
        unsigned int num;
        unsigned int numtwo;


        FILE* ff = fopen(name,"r");
        if(ff == NULL) {
             fprintf(stderr, "Error \n");
            return -1;
        }

        char *tempp = (char*) malloc(lines + 1 );

        while(fgets(tempp,lines+1,ff) != NULL){

              sscanf(tempp,"%u %u",&num, &numtwo);

              printf("counter: %u | ",counter);
              printf("Value A: %u ",num);
              printf("Value B: %u \n",numtwo);

              counter++;
        }
        free(tempp);
        tempp = NULL;


return 0;
}

您没有分配足够的 space 来阅读每一行。您将 行数 用作行的 长度 ,但它们并不相同。

您为 ttemp 分配了 4 个字节 (lines + 1),用于在一行中读取。然而,文本的第一行有 6 个字符。所以第一次调用fgets只读取前3个字节,即"55 "。这就是 sscanf 解析的内容。下一次调用获取接下来的 3 个字节,即 "09\n" 并在换行符处停止读取,因此只解析出第一个数字。

由于你在循环中使用fgets来读取行并打印内容,你实际上不需要知道有多少行。但是,您确实需要知道一行的最大长度。由于您正在读取两个十进制整数,因此 30 个字节应该足以读取整行。所以做一个那个大小的固定缓冲区:

    char tempp[30];
    while(fgets(tempp,sizeof(tempp),ff) != NULL){
        ...

在您更新的代码和数据中,问题肯定是 lines 的值对于您的使用来说太小了。您正在使用它来衡量 tempp 缓冲区需要多少 space,但这需要最大行数 width(加一个用于换行,另一个用于终结者)。相反,您给它的是一行 count,而文件的那一行只有几行。因此,fgets() 会在多个呼叫中打断您的线路。

您确实可以预先扫描文件以找到合适的宽度,然后分配那么多,但是在这里使用 fgets 而不是 fscanf 会很麻烦。对于许多问题确实有理由更喜欢它,但您的问题看起来不像其中之一。通过这样做,您可以节省大量的麻烦和代码:

unsigned num, numtwo;
while (fscanf(ff, "%u%u", &num, &numtwo) == 2) {
    // update counter, print results, etc...
}

你的根本问题是你的 lines 变量。它太小了。 (应该是 "line size" 吗?)

我建议您去掉 lines 变量、tempp 变量和 malloc 调用。声明单个数组

char line[1000];

1000 个字符对于任何可以想象的输入来说应该足够长了。那么你的循环可以是

while(fgets(line, sizeof(line), ff) != NULL) { ...

您的其余代码看起来没问题。进行此更改后,您应该不会再遇到号码被奇怪地分解的问题了。