从C中的txt文件中读取整数

Posted

技术标签:

【中文标题】从C中的txt文件中读取整数【英文标题】:Reading integers from txt file in C 【发布时间】:2017-08-23 11:48:22 【问题描述】:

我正在制作一个文件阅读器,它可以从文件中逐行读取整数。问题是它不起作用。我认为我以错误的方式使用 fscanf 。有人可以帮我吗?

我已经在其他问题中寻找答案,但我找不到任何解释我的代码为什么不起作用的东西。

int read_from_txt()
    FILE *file;
    file = fopen("random_numbers.txt", "r");
    //Counting line numbers to allocate exact memory
    int i;
    unsigned int lines = 0;
    unsigned int *num;
    char ch;
    while(!feof(file))
        ch = fgetc(file);
        if (ch == '\n')
            lines++;
        
    
    //array size will be lines+1
    num = malloc(sizeof(int)*(lines+1));
    //storing random_numbers in num vector
    for(i=0;i<=lines;i++)
        fscanf(file, "%d", &num[i]);
        printf("%d", num[i]);
    
    fclose(file);

txt文件是这样的:

12 
15
32
68
46
...

但是这段代码的输出一直给出“0000000000000000000...”

【问题讨论】:

fgetc 循环之后,文件指针位于文件末尾。您需要rewind 再次阅读该文件。 @Lashane file 以文本模式打开。对应于编译器对文本文件的 C 库理解的文本文件会将\n\r\n\r 转换为'\n'if (ch == '\n') 就足够了。如果需要处理其他文本文件,则会出现许多其他问题,超出了本文的范围。 提示:任何时候代码没有按预期运行并且代码正在执行 I/O,添加代码以检查 I/O 函数的返回值,例如 fscanf(file, "%d", &amp;num[i]);,这会显示一个问题 - 这个节省您的时间。 让我们continue this discussion in chat。 while(!feof(file))is always wrong。 fgetc返回 int 而不是 char 【参考方案1】:

您忘记“倒回”文件:

fseek(file, 0, SEEK_SET);

您的读取过程会遍历文件两次 - 一次用于计算行数,另一次用于读取数据。在第二遍之前,您需要回到文件的开头。

请注意,您可以通过使用realloc 在单遍中执行此操作:将循环中的数字读取到临时int 中,并且对于每次成功读取,通过调用@ 将num 数组扩展一个987654325@。这将根据需要扩展缓冲区,您无需倒带。

在重新分配给num之前,请仔细检查realloc的结果,以避免内存泄漏。

【讨论】:

【参考方案2】:

您可以尝试使用标准 IO 中的 getline 函数,并仅使用一个循环将解析后的数字添加到数组中。请参阅下面的代码。请查看https://linux.die.net/man/3/getline

此外,您可以使用atoistrtoul 函数将读取的行转换为整数。随时查看https://linux.die.net/man/3/atoi 或https://linux.die.net/man/3/strtoul

下面的代码评估一个包含数字列表的文件并将这些数字添加到一个 C 整数指针

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

int main(int argc, char ** argv) 
    FILE * file;

    file = fopen("./file.txt", "r");

    size_t read;
    char * line = NULL;
    size_t line_len = 0;

    size_t buffer_size = 10;
    int * buffer = (int *)malloc(sizeof(int) * buffer_size);

    int seek = 0;
    while((read = getline(&line, &line_len, file)) != -1) 
        buffer[seek++] = atoi(line);

        if (seek % 10 == 0) 
            buffer_size += 10;
            buffer = (int *)realloc(buffer, sizeof(int) * buffer_size);
        
    

    for (int i = 0; i < seek; i++) 
        printf("%d\n", buffer[i]);
    

    free(buffer);
    fclose(file);

如果您不确定应该使用哪种转换函数。您可以在What is the difference between sscanf or atoi to convert a string to an integer? 上查看atoisscanf 之间的区别

【讨论】:

请注意,atoi 提供了绝对 no 错误检查,任何依赖于 buffer[X] 的后续代码都包含该范围内的 unsigned0 - INT_MAX 无法验证 buffer[X] 是否包含有效值。 (最好使用strtoul 进行错误检查)。接下来,将realloc 的返回值分配给指针本身(而不是tmp 指针)可能会因丢失对原始内存块的引用而造成内存泄漏。 (更好void *tmp = realloc(buffer, sizeof *buffer * buffer_size); if (tmp) buffer = tmp;。(也不需要投射) @DavidC.Rankin 是对的,您可以使用sscanfstrtoul 检查转换的完整性。此外,您应该检查指针完整性以避免可能的泄漏或内存问题。谢谢大卫 C。

以上是关于从C中的txt文件中读取整数的主要内容,如果未能解决你的问题,请参考以下文章

从 .txt 文件中读取未知大小的整数二维数组的最有效方法是啥?

从给定的 txt 中读取所有数字并将它们输出到 c 中的新文件中

C/s从文件(TXT)中读取数据插入数据库

将txt文件中的行批量读取到变量中

c语言读取txt文件内容

C语言求助:如何将.txt文件中的字符串存入字符数组?这个 .txt 文件是从命令行参数 btw 中读取的。