我可以使用fscanf仅从包含字符和整数的文本中获取数字吗?

我可以使用fscanf仅从包含字符和整数的文本中获取数字吗?,c,scanf,C,Scanf,我想从包含字符和数字的文件中提取数字 例如: + 321 chris polanco 23 我想跳过“+”而只得到321 这是我到目前为止的代码 while(fscanf(update, "%d", &currentIn->userid) != EOF){ currentIn->index = index; rootIn = sort(rootIn, currentIn); index = index + 1; currentIn = mal

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

例如:

+ 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
,它会得到它找到的第一个数字,但我错了。如果你们有更好的方法的话,我愿意采用更好的方法。

我建议使用+组合来处理每一行,而不是使用fscanf()(稍后会遇到格式问题)

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

char line[MAX_LINE_LEN + 1];

While ( fgets(line, sizeof line, update) )
{
  if(sscanf(line+2, "%d",  &currentIn->userid) != 1)
  {
   /* handle failure */
  }
  ...
}
这将跳过非数字(即
%*[^0-9]
部分),后跟一个整数。被抑制的赋值不计算在内,因此
==1
确保您得到一个数字

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

  • ungetc('a',更新)将首先给出一个非数字来读取
  • while((fscanf(更新,“%*[^0-9]”),fscanf(更新,“%d”,¤tIn->userid))==1)
  • 或:

    while (fscanf(update, "%*[^0-9]%d", &currentIn->userid) == 1 ||
           fscanf(update, "%d", &currentIn->userid) == 1)
    {
        ...
    }
    
  • 根据您认为更可能的策略,您可以颠倒这两个
    fscanf()
    策略的顺序。对于
    scanf()
    函数系列,如果数字字符串太长,以至于无法在
    int
    中表示数字,则始终会出现问题;你会有未定义的行为。我不会试图解决这个问题


    这将在每行获取多个数字,每次调用一个。如果您希望每行有一个数字,或者希望控制每行的处理方式,请使用
    fgets()
    readline()
    读取该行,然后使用
    sscanf()
    进行分析。这样做的一个优点是,如果您选择这样做,您可以使用诸如
    strtol()
    之类的谨慎函数将数字转换为数字。

    使用
    std::string
    将导致C程序中的语法错误。我的程序是用C编写的。我认为这是C++的,如果行以数字开头(如果没有非数字可以跳过),则此操作将失败。你需要
    while((fscanf(update,“%*[^0-9]”)、fscanf(update,“%d”、¤tIn->userid))==1)
    ,这有点难看。哦,是的,你是对的。如果在第一个数字之前没有垃圾,则失败。我猜是一个初始的
    ungetc('a',update)
    几乎和double
    fscanf()
    一样难看,尽管它也可以工作,并且不会影响循环的每次迭代。有没有办法使字符行更通用。如果我们不知道长度怎么办?fgets()将只读取指定数量的字节,因此没有问题。如果它可以读取整行,那么它将在下一次迭代中从留下的位置继续(顺便说一句,它可能会导致您要读取的整数的位置出现问题)。否则,您可以扫描每行
    (在对其执行sscanf()之前)并忽略,直到看到
    \n
    字符,以便知道您在下一行。
    while (fscanf(update, "%*[^0-9]%d", &currentIn->userid) == 1 ||
           fscanf(update, "%d", &currentIn->userid) == 1)
    {
        ...
    }