【问题标题】:stdio.h fscanf format specifiersstdio.h fscanf 格式说明符
【发布时间】:2015-01-31 17:32:19
【问题描述】:

我的文件将包含两个数字,它们之间有可变空格,或者只是一个空行。我需要知道输入何时只是一个空白行,然后不使用 fscanf 分配给这些变量。

在做:

FILE *pFile = fopen (my_file, "r");
if (pFile == NULL) perror ("Error opening file");
int succ = 1, num1 = 0, num2 = 0; 
while (succ != EOF)
{
  succ = fscanf(pFile, "%d   %d", &num1, &num2);
}

非常适合正确检测所有数字,但不能正确检测换行符。 我试过了:

fscanf(pFile, "%d   %d %*[^\n]", &num1, &num2);

但它总是正确地分配给这两个数字。我希望能够根据 succ 是否为 2(表示也分配了两个数字)或 0(表示空行)来创建一个 switch 语句来执行其他逻辑。

如果可能,我宁愿避免使用 getline;使用 iostream 与 stdio 函数混合的东西似乎效率低下。

我尝试了this guys suggestion,但没有成功,虽然从逻辑上讲我认为它会起作用,但它没有。

老实说,我什至不明白为什么像

"%d   %d \n"

行不通。很简单……扫描文件直到换行,返回完成了多少作业,就是这样!

【问题讨论】:

  • 在C语言中,我建议使用fgets()!然后sscanf() 或更精细的解析。不了解 C++。
  • 不知道行多长,这是第二个参数需要的,我只需要换行之前的所有内容
  • 您也可以重复使用getchar()。这也许是您最好的选择。
  • 根据这个答案:stackoverflow.com/questions/13221844/…,在格式说明符“%d %d”的末尾添加一个空格。
  • @ThomasMatthews - 一个好主意,但在实践中它根本不会改变程序的行为;因为我不想检测空行。这将吃掉该行的其余部分和空白行,然后继续

标签: c file-io stdio


【解决方案1】:

"%d %d \n" 无法实现 OP 目标,因为任何空白指令都会消耗任何空白。使用 ' ''\n' 没有区别,它们都消耗 0 个或多个空格。 (预计在'[]' 说明符中)

OP 想要检测 '\n'fscanf() 不是一个好的选择。 fgets() 更好。

#define N (100 /* longest line */)
char buf[N];
while (fgets(buf, sizeof buf, pFile) != NULL) {
  int cnt = sscanf("%d%d",&num1, &num2);
  switch (cnt) {
     case 0: Handle_NoNumbers(); break; 
     case 1: Handle_1Number(); break; 
     case 2: Handle_Success(); break; 
  }
}

fscanf(stream, "%d", &num) 中的'%d' 指定消耗数字前的所有前导空格,而不考虑'\n'' ' 等。

如果代码必须使用fscanf(),则代码需要在调用fscanf(... "%d")之前使用前导空格,以区分'\n'' '

// Consume white space except \n and EOF
int consume_ws(FILE *pFile) {
  do {
    int c = fgetc(pFile);  // could use fscanf(...%c...) here
    if (c == '\n' || c == EOF) return c;
  } while (isspace(c));
  ungetc(c, pFile);  // put the char back
  return 0;
}

...
while(1) {
  int num[2];
  int i;
  for (i = 0; i < 2; i++) { 
    if (consume_ws(pFile)) {
      Handle_ScantData();  // Not enough data
      return;
    }
    if (1 != fscanf(pFile, "%d", &num[i]) {
      Handle_NonnumericData();
      return;
    }
  }
  int ch = consume_ws(pFile);
  if (ch == 0) Handle_ExtraData();

  // Else do something with the 2 numbers

  if (ch == EOF) return;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-13
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多