从文件中的一行中读取任意数量的空格分隔的字符
我有一个文件,它在一行中有任意数量的数字可以读取为整数。在一个最小的,可重复的例子,我创建了一个只包含以下行文件test.dat
:从文件中的一行中读取任意数量的空格分隔的字符
1 2 3 4
然后我尝试使用fgets
和strtok
来实现这一目标:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
FILE* fileptr;
fileptr = fopen("test.dat","r");
char line[500];
char *token;
int array[20];
int i = 0;
fgets(line,300,fileptr);
token = strtok(line," ");
array[i] = atoi(token);
printf("%d\n", array[i]);
i++;
while(token != NULL){
token = strtok(line," ");
array[i] = atoi(token);
printf("%d\n", array[i]);
i++;
}
return 0;
}
但这会导致印刷21行1
's,接着是0
的632行。最后它给出了分段错误,因为i
增长大于20,分配的空间为array
。我不明白的是为什么会打印600多行文件,以及为什么我永远无法读取文件中的数字1
以外的内容。我错过了什么?
注意:我更愿意继续阅读文件fgets
,因为这将是对读取整个文件的现有子程序的简单修改。
有几件事情:
- 你不限制你的环路的
array
- 你的循环中能够幅度没有妥善安排。所有的存储应该在循环内完成;以前的异常值不需要在那里。
- 您在循环中调用
strtok
是错误的。 A 延续strtok
的最初开始应指定NULL
作为第一个参数。有关更多信息和使用示例,请参阅strtok
的文档。
能够解决这些问题的一个例子是在这里:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE* fileptr = fopen("test.dat","r");
if (fileptr == NULL)
{
perror("Failed to open file: ");
return EXIT_FAILURE;
}
char line[500];
int array[20];
const size_t max_size = sizeof array/sizeof *array;
size_t i = 0;
if (fgets(line,300,fileptr))
{
char *token = strtok(line," ");
while (i < max_size && token != NULL)
{
array[i] = atoi(token);
printf("%d\n", array[i]);
++i;
token = strtok(NULL, " ");
}
// use array and i for whatever you needed
}
return EXIT_SUCCESS;
}
输出
1
2
3
4
感谢您的详细解答。在第一次通话之后将NULL传递给'strtok'的逻辑是什么? – sodiumnitrate
@sodiumnitrate请参见[strtok'的文档](http://en.cppreference.com/w/c/string/byte/strtok)。它会做得比解决这个问题的目的要好得多,并为您提供一个很好的网站,为过程中的未来查询添加书签。 – WhozCraig
嗯,不清楚为什么在'与fgets(线,300,fileptr)300;'。我期望'fgets(line,sizeof line,fileptr);' – chux
@chux没有很好的理由 - 我没有写出原来的代码来自哪一行。我会解决它。谢谢。 – sodiumnitrate
如果目标是获得“空格分隔的字符”,那么'strtok()'很好。然而,由于该令牌立即运行atoi(),因此使用'strtol()'而不是'strtok()/ atoi()'更有意义,因为[解析多个空格分隔的整数的字符串](https:/ /*.com/q/28233450/2410359) – chux