【问题标题】:Trying to read a two numbers from a text file试图从文本文件中读取两个数字
【发布时间】:2021-07-15 21:51:47
【问题描述】:

我正在尝试从文本文件中读取两个数字。我用的是strtok,分隔符是" "。文本文件(名为data.txt)文件只有两个数字,行是"3 5"。但是程序崩溃了……感谢您的帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
    
int main(){
    
    FILE *data;
    data = fopen("data.txt", "r");
    
    int m, n;
    char *line, *number;
    while(!feof(data))
    {
        fscanf(data, "%s", line);
        number = strtok(line, " ");     
        m = atoi(number);       
        number = strtok(NULL, " ");     
        n = atoi(number);
    }       
}

【问题讨论】:

  • line 是一个指针。它指向什么变量或内存空间?
  • 另见stackoverflow.com/q/5431941/10622916。一般来说,您应该检查所有返回值以确保没有发生错误。
  • while(!feof(data)) 在任何读取出现未定义行为之前,请检查 fscanf 返回的值。
  • 如果你只是去strtok,你不妨在scanf中使用"%d%d"。但是如果你打算使用%s,你必须添加一个比缓冲区大小小一的最大字段宽度。例如char line[32]; ... scanf("%31s", line);。由于您为缓冲区分配了零,因此显然存在问题。
  • @bruno while(!feof(data)) before any read has an undefined behavior 不受 C 规范支持。 fopen() --> “流的错误和文件结束指示符已清除。”和feof()“函数测试流指向的流的文件结束指示符。”它定义明确,即使它不是 OP 应该做的。

标签: c file-io io string.h


【解决方案1】:

line 是一个未初始化的指针,它不指向任何有效的内存位置,因此您不能使用它来存储数据,而是使用数组。

while(!feof(data))is not what you'd want to use 来控制你的阅读周期。

使用fgets/sscanf解析值,简单易行:

FILE *data;
data = fopen("data.txt", "r");
int m, n;
char line[32];

if (data != NULL)
{
    while (fgets(line, sizeof line, data)) // assuming that you want to have more lines
    {
        if(sscanf(line, "%d%d", &m, &n) != 2){
            // values not parsed correctly
            //handle parsing error
        }
    }
}

或者@chux pointed out,检测线上多余的垃圾:

 char end;  
 if(sscanf(line, "%d%d %c", &m, &n, &end) != 2) {
     // if more characters exist on the line
     // the return value of sscanf will be 3
 }

如果文件中的值可能超出int 的范围,请考虑使用strtol 而不是sscanf

【讨论】:

  • 当前几个字符不是整数时,m和n的值为零。请问如何跳过无效字符?
  • @smiili,有,如果你知道这些字符是什么,或者至少有多少,它会有所帮助,如果不知道它会稍微复杂一点,也许是一个新问题的问题。
  • 次要:检测线路上的额外垃圾:char end; if(sscanf(line, "%d%d %c", &amp;m, &amp;n, &amp;end) != 2){
  • @chux-ReinstateMonica 这是一个很好的补充
猜你喜欢
  • 1970-01-01
  • 2012-10-06
  • 2016-12-06
  • 1970-01-01
  • 2014-05-11
  • 2021-12-19
  • 1970-01-01
  • 2014-11-07
  • 2013-03-10
相关资源
最近更新 更多