【问题标题】:fscanf not scanning any numbersfscanf 不扫描任何数字
【发布时间】:2016-05-04 11:34:26
【问题描述】:

我目前正在开发一个简单的 C 应用程序。它将单个文件作为命令行参数,其格式如下:

1,2,3
4,5,6
7,8,9
etc.

但是,无论出于何种原因,fscanf 从不扫描数字!这是一个例子:

#include <stdio.h>

int main(int argc, char **argv) {
    FILE *file = fopen(*argv, "r");
    int i1, i2, i3;
    while (fscanf(file, "%d,%d,%d", &i1, &i2, &i3) == 3) {
        printf("Doing stuff with %d, %d, and %d...\n", i1, i2, i3);
    }
    fclose(file);
    return 0;
}

如果您使用文件名作为参数运行它,那么它会立即退出,因为fscanf 返回 0。我已经尝试了几种变体,但无济于事。如何让fscanf 正确读取数字?

【问题讨论】:

  • fopen(*argv, "r") --> fopen(*++argv, "r")fopen(argv[1], "r")
  • 为什么不检查fopen()的返回值?
  • @BLUEPIXY facepalm 你能把它作为答案发布吗?
  • @LegionMammal978 不要假设。检查并确定。 :)
  • @SouravGhosh 虽然你有一个一般性的观点——对于chrissake,总是检查返回值! ——,在这里没用!该程序可以打开argv[0] 好吧,可惜在特殊情况下它只能从这些字节中扫描三个逗号分隔的数字;-)。

标签: c scanf format-specifiers


【解决方案1】:

肤浅的回答:打开了错误的文件,因为代码应该使用argv[1]而不是*argv

让我们深入了解一下。

代码有问题,至少在 2 个地方缺少错误检查。

  1. FILE *file = fopen(*argv, "r"); 之后没有对 file 进行测试。这种经典检查不会检测到 OP 的问题,因为文件(可执行文件)是可打开的。

  2. fscanf(file, "%d,%d,%d", &amp;i1, &amp;i2, &amp;i3) 的返回值只经过了轻微测试。 EOF 0 1 2 3 的返回值是可能的,但只有 EOF 3 是预期的。如果对非EOF 3 的代码进行了测试,很快就会发现问题。

要吸取的教训:确保代码,尤其是行为不端的代码,有足够的错误检查。从长远来看,可以节省编码人员的时间。

#include <stdio.h>

int main(int argc, char **argv) {
  if (argc != 2) {
    fprintf(stderr, "Unexpected argument count %d.\n", argc);
    return 1;
  } 
  FILE *file = fopen(argv[1], "r");
  if (file == NULL) {
    fprintf(stderr, "Unable to open file: \"%s\"", argv[1]);
    return 1;
  } 
  int i1, i2, i3;
  int n;
  while ((n = fscanf(file, "%d,%d,%d", &i1, &i2, &i3)) == 3) {
    printf("Doing stuff with %d, %d, and %d...\n", i1, i2, i3);
  }
  if (n != EOF) {
    fprintf(stderr, "Unexpected scan failure count %d\n", n);
    return 1;
  }
  fclose(file);
  return 0;
}

【讨论】:

  • 大部分都在早期的迭代中检查过。我检查了文件(不是NULL),查看了fscanf 的返回值(它一直返回0),并检查了in 的值(它们从未改变。)跨度>
【解决方案2】:

正如 BLUEPIXY 所述,您应该使用 argv 数组的第二个元素:argv[1]

FILE *file = fopen(argv[1], "r");

第一个元素(argv[0]*argv)是正在执行的程序的名称 - 它不是要打开的正确文件。

【讨论】:

    猜你喜欢
    • 2012-07-14
    • 2012-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    相关资源
    最近更新 更多