【问题标题】:Strtol doesn't return the correct endptr - CStrtol 没有返回正确的 endptr - C
【发布时间】:2019-11-17 20:42:54
【问题描述】:

我必须从文件行中解析数据,为此我现在使用 strtol() 函数。

例如,我在文本文件中有这一行:1 abc

例如,这是一个无效行,因为该特定行必须包含一个且仅一个整数值。

现在当我以这种方式使用 strtol 时:

    FILE *fs;
    fs = fopen("file.txt", "r");
    char* ptr = NULL; // In case we have string except for the amount
    char lineInput[1024]; // The max line size is 1024
    fscanf(fs, "%s", lineInput);
    long numberOfVer = strtol(lineInput, &ptr, BASE);
    printf("%lu\n%s\n", numberOfVer, ptr); // Here I test the values, I expect to get 1 followed by newline and abc
    if (numberOfVer == 0 || *ptr != '\0') { // Not a positive number or there exists something after the amount!
        fprintf(stderr, INVALID_IN);
        return EXIT_FAILURE;
    }

但是,ptr 字符串不是“abc”或“abc”,它是一个空字符串... 这是为什么?根据文档,它必须是“abc”。

【问题讨论】:

标签: c pointers file-io strtol


【解决方案1】:

scanf("%s") 跳过空格。所以如果你有输入 "1 abc" 并用

扫描它
fscanf(fs, "%s", lineInput);

lineInput 的内容最终变为"1",字符串的其余部分留在输入缓冲区中,为下一次输入操作做好准备。

读取行的常用函数是fgets()

    FILE *fs;
    fs = fopen("file.txt", "r");
    char* ptr = NULL; // In case we have string except for the amount
    char lineInput[1024]; // The max line size is 1024
    // using fgets rather than fscanf
    fgets(lineInput, sizeof lineInput, fs);
    long numberOfVer = strtol(lineInput, &ptr, BASE);
    printf("%ld\n%s\n", numberOfVer, ptr); // Here I test the values, I expect to get 1 followed by newline and abc
    //      ^^^ numberOfVer is signed
    if (numberOfVer == 0 || *ptr != '\0') { // Not a positive number or there exists something after the amount!
        fprintf(stderr, INVALID_IN);
        return EXIT_FAILURE;
    }

【讨论】:

  • 由于'\n'*ptr != '\0' 可能永远为真。
  • @chux-ReinstateMonica 但是如果我们下面没有一行呢?
  • @HelpMe:在 un*x 系统中,文本文件以换行符以外的内容结尾是非常不寻常的。基本概念是一行包含'\n' 字符。例如,某些编译器在输入以"}"(不是"}\n")结尾的文件时会发出诊断信息。
  • @pmg 如果我的文本文件只包含一行“123”而没有其他内容,则在此 123 之后没有换行符。所以,当我在此行 strtol 函数上使用时,什么是endptr 的值?
  • @HelpMe:在那种(不寻常的)情况下,endptr 指向'\0',就在'3' 之后。我在fgets() 之后经常做的是删除换行符(如果存在):lineInput[strcspn(lineInput, "\n")] = 0;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
相关资源
最近更新 更多