1

我想从包含字符和数字的文件中提取数字。

例如:

+ 321 chris polanco 23

我想跳过“+”,只得到 321。

这是我到目前为止的代码。

while(fscanf(update, "%d", &currentIn->userid) != EOF){
    currentIn->index = index;
    rootIn = sort(rootIn, currentIn);
    index = index + 1;
    currentIn = malloc(sizeof(Index));
}

我在想,既然我有%d它会得到它找到的第一个数字,但我错了。如果你们有的话,我愿意接受更好的方法。

4

2 回答 2

2

我建议使用fgets() + sscanf()组合来处理每一行,而不是与 fscanf() 苦苦挣扎(并在以后遇到格式问题) 。

如果您知道您感兴趣的整数从文件每一行的第三个位置开始,那么您可以line+2在 sscanf() 中读取它。否则,您可以根据输入文件的格式修改 sscanf() 格式字符串。

char line[MAX_LINE_LEN + 1];

While ( fgets(line, sizeof line, update) )
{
  if(sscanf(line+2, "%d",  &currentIn->userid) != 1)
  {
   /* handle failure */
  }
  ...
}
于 2013-10-16T21:04:23.417 回答
0
while (fscanf(update, "%*[^0-9]%d", &currentIn->userid) == 1)
{
    ...
}

这会跳过非数字(即%*[^0-9]部分),后跟一个整数。不计算被抑制的分配,因此== 1确保您得到一个数字。

不幸的是,如果文件中的第一个字符是数字,就会遇到问题——正如Chris Dodd所指出的那样。有多种可能的解决方案:

  1. ungetc('a', update);会先给出一个非数字来读取。
  2. while ((fscanf(update, "%*[^0-9]"), fscanf(update, "%d", &currentIn->userid)) == 1)
  3. 或者:

    while (fscanf(update, "%*[^0-9]%d", &currentIn->userid) == 1 ||
           fscanf(update, "%d", &currentIn->userid) == 1)
    {
        ...
    }
    

根据您认为哪个更有可能,您可以颠倒这两个fscanf()策略的顺序。对于scanf()函数族,如果数字字符串太长以至于无法在int;中表示数字,则总是会出现问题。你得到未定义的行为。我不试图解决这个问题。

这将在每行中提取多个数字,每次调用一个。如果您想要每行一个数字,或者想要控制每行的处理方式,请使用fgets()readline()读取该行,然后sscanf()进行分析。这样做的一个好处是,如果您愿意,您可以使用诸如strtol()将数字转换为数字之类的谨慎功能。

于 2013-10-16T21:05:40.717 回答