【问题标题】:in C, what is "%n" ? and how does this code work? [duplicate]在 C 中,什么是 "%n" ?这段代码是如何工作的? [复制]
【发布时间】:2013-05-17 13:07:38
【问题描述】:

在c编程语言中,占位符“%n”是什么? 以及下面的代码是如何工作的?

    char s[150];
    gets(s);
    int read, cur = 0,x;
    while(sscanf(s+cur, "%d%n", &x, &read) == 1)
    {
        cur+= read;
        /// do sth with x
    }

-- 此代码获取一行作为字符数组,然后扫描此字符数组中的数字, 例如:如果*s="12 34 567" 第一次x = 12 下次x = 34 终于x = 567

【问题讨论】:

  • 有人应该发布一个标准或规范或手册或书籍来解释这样的事情。可惜在地球上的任何地方都找不到。
  • @EricPostpischil 我希望你是在讽刺。
  • 我不鼓励使用 gets,就像 C11 标准通过弃用它所做的那样。它引入了缓冲区溢出的问题。您可以改用fgets 来修复此错误。此外,忽略任何标准 C 函数 的返回值可能会导致未定义的行为。也许您可以搜索“opengroup fgets”以找到手册,跳到“返回值”部分并编写代码以确保在逻辑继续之前返回值符合预期。您可能会省去很多哭泣和浪费时间!

标签: c format scanf


【解决方案1】:

来自手册页

n      Nothing is expected; instead, the number of characters  consumed
              thus  far  from  the  input  is stored through the next pointer,
              which must be a pointer to  int.   This  is  not  a  conversion,
              although  it can be suppressed with the * assignment-suppression
              character.  The C standard says: "Execution of  a  %n  directive
              does  not increment the assignment count returned at the comple‐
              tion of execution" but the Corrigendum seems to contradict this.
              Probably it is wise not to make any assumptions on the effect of
              %n conversions on the return value.

【讨论】:

  • 更正矛盾是错误的。最好遵循最新标准,其中更正并包含错误示例。
【解决方案2】:

这里,"%n" 表示到目前为止读取的字符数。

【讨论】:

    【解决方案3】:

    %n存储输入字符串中已经处理成相关参数的字符个数;在这种情况下,read 会得到这个值。我稍微重写了你的代码,以便在代码执行时转储每个变量发生的情况:

    #include <stdio.h>
    
    int main(int argc, char **argv)
      {
      char *s = "12 34 567";
      int read=-1, cur = 0, x = -1, call=1;
    
      printf("Before first call, s='%s'  cur=%d   x=%d   read=%d\n", s, cur, x, read);
    
      while(sscanf(s+cur, "%d%n", &x, &read) == 1)
        {
        cur += read;
    
        printf("After call %d, s='%s'  cur=%d   x=%d   read=%d\n", call, s, cur, x, read);
    
        call += 1;
        }
      }
    

    产生以下内容

    Before first call, s='12 34 567'  cur=0   x=-1   read=-1
    After call 1,      s='12 34 567'  cur=2   x=12   read=2
    After call 2,      s='12 34 567'  cur=5   x=34   read=3
    After call 3,      s='12 34 567'  cur=9   x=567  read=4 
    

    分享和享受。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 1970-01-01
      • 2012-08-31
      • 2015-11-27
      • 2012-11-04
      • 1970-01-01
      • 2017-04-09
      相关资源
      最近更新 更多