2017-09-07 46 views
1

我有一个文件,它在一行中有任意数量的数字可以读取为整数。在一个最小的,可重复的例子,我创建了一个只包含以下行文件test.dat从文件中的一行中读取任意数量的空格分隔的字符

1 2 3 4 

然后我尝试使用fgetsstrtok来实现这一目标:

#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,因为这将是对读取整个文件的现有子程序的简单修改。

+0

嗯,不清楚为什么在'与fgets(线,300,fileptr)300;'。我期望'fgets(line,sizeof line,fileptr);' – chux

+0

@chux没有很好的理由 - 我没有写出原来的代码来自哪一行。我会解决它。谢谢。 – sodiumnitrate

+0

如果目标是获得“空格分隔的字符”,那么'strtok()'很好。然而,由于该令牌立即运行atoi(),因此使用'strtol()'而不是'strtok()/ atoi()'更有意义,因为[解析多个空格分隔的整数的字符串](https:/ /stackoverflow.com/q/28233450/2410359) – chux

回答

1

有几件事情:

  • 你不限制你的环路的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 
+0

感谢您的详细解答。在第一次通话之后将NULL传递给'strtok'的逻辑是什么? – sodiumnitrate

+1

@sodiumnitrate请参见[strtok'的文档](http://en.cppreference.com/w/c/string/byte/strtok)。它会做得比解决这个问题的目的要好得多,并为您提供一个很好的网站,为过程中的未来查询添加书签。 – WhozCraig

相关问题