【问题标题】:Casting char from file read line to int dumps core将字符从文件读取行转换为 int 转储核心
【发布时间】:2022-01-09 17:17:58
【问题描述】:

嘿,我对 c 语言还很陌生,正在尝试代码的出现。第一天的任务是读入一个包含以下文本(代表)的文件:

forward 8
up 6
down 3
...

目标是将末尾的数字添加到数字前面的单词选择的 int 中。

由于我是 c 新手,所以我决定逐步执行此操作并读取以下代码,只需读出第一个字母以决定执行哪个操作以及我要存储为 int value 的数字:

FILE * file = fopen("./puzzle.input", "r");
char line[255];
while (fgets(line, sizeof(line), file)) {
    if (line[0] == 'f') {            
        last_pos = strlen(line);
        int value;
        sscanf(line[8], "%d", &value);            
    }

这失败了:

[1]    3931 segmentation fault (core dumped)

奇怪的是,当我printf("%c", line[8]) 时输出了正确的数字。所以我怀疑选角出了大问题。我用atoi 试过了,但也没有用。只需使用(int) 进行投射,就会返回一个错误的数字,总是在 50 左右。 现在我的问题:

  • 为什么 (int) 回馈 50 左右的东西
  • 如何解决此问题
  • 以后如何防止这种情况发生。

非常感谢,期待学习!

【问题讨论】:

  • line[8]char(一个字母或 -128 到 127 之间的数字),sscanf 想要一个指向以空字符结尾的字符串的指针。当它试图将你给它的数字解释为内存地址时,它就会出错。你可以试试line+8(跳过前 8 个字符)。
  • 第 50 个东西 - 见 en.wikipedia.org/wiki/ASCII -- 48 到 57 是数字字符的代码。
  • sscanf 的参数是指向 char 的指针,试试&line[8]。 (同时启用编译器警告。)但总体而言,这是构建解析器的一种非常脆弱的方式,可能是strtok 将其拆分为字段的行,或其他东西。
  • 如果该行小于 8 个字节的数据怎么办?

标签: c scanf fgets atoi


【解决方案1】:

有几种方法可以读取文本后的整数。您可以添加一个临时缓冲区来跳过第一个单词。

while (fgets(line, sizeof(line), file))
{
    int value = 0;
    char temp[255];
    if (sscanf(line, "%s %d", temp, &value) == 2)
        printf("%s, %d\n", temp, value);
    //if (strcmp(temp, "forward") == 0) printf("...");
}

或者使用strstr查看行是否包含"forward"

while (fgets(line, sizeof(line), file))
{
    const char* key = "forward";
    if (strstr(line, key) == line) //line starts with "forward"
    {
        int value = 0;
        if (sscanf(line + strlen(key), " %d", &value) == 1)
            printf("%s, %d\n", key, value);
    }
}

或使用strtok 将行分解为单词,并使用atoi 将单词转换为整数。

确保初始化变量,否则它将包含留在内存中的随机值。

sscanf(line[8], "%d", &value); 如您所见,不正确。第一个参数应该是一个字符串,但line[8] 是一个字符,编译器应该发出警告。检查if (line[0] == 'f') 的问题是该行可能包含"forw 8",您不想通过空终止字符读取它。

【讨论】:

    猜你喜欢
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多