从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", &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
此外,您可以使用atoi
或strtoul
函数将读取的行转换为整数。随时查看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? 上查看atoi
和sscanf
之间的区别
【讨论】:
请注意,atoi
提供了绝对 no 错误检查,任何依赖于 buffer[X]
的后续代码都包含该范围内的 unsigned
值0 - INT_MAX
无法验证 buffer[X]
是否包含有效值。 (最好使用strtoul
进行错误检查)。接下来,将realloc
的返回值分配给指针本身(而不是tmp
指针)可能会因丢失对原始内存块的引用而造成内存泄漏。 (更好void *tmp = realloc(buffer, sizeof *buffer * buffer_size); if (tmp) buffer = tmp;
。(也不需要投射)
@DavidC.Rankin 是对的,您可以使用sscanf
或strtoul
检查转换的完整性。此外,您应该检查指针完整性以避免可能的泄漏或内存问题。谢谢大卫 C。以上是关于从C中的txt文件中读取整数的主要内容,如果未能解决你的问题,请参考以下文章
从 .txt 文件中读取未知大小的整数二维数组的最有效方法是啥?