【问题标题】:scanf get multiple values at oncescanf 一次获取多个值
【发布时间】:2015-09-07 23:53:17
【问题描述】:

我需要从单行中一次性获取不同的输入。特别是我需要得到一个char,然后,根据我刚刚读取的char值,它可以是一个字符串和一个int或一个字符串、一个int和另一个字符串等等。

示例输入可能是:

c test 20 good
d test 10

这是我写的:

char c, * alpha, * beta;
int val;
c = getchar();
printf("%c\n\n", c);

switch (c){
    case 'd': scanf("%s %d", alpha, &val); printf ("%c %s %d", c, alpha, val); break;
    case 'c': scanf("%s %d %s", alpha, &val, beta);  printf ("%c %s %d %s", c, alpha, val, beta); break;
    default: return 0;
}

除了需要换行符(即我按回车键)来获取第一个字符之外,它在 d 情况下工作正常,但在 c 情况下会出现段错误。我该怎么做?

【问题讨论】:

  • alphabeta 指向无处。你应该为它们分配一些内存。
  • chars 的数组,用于 alphabetamalloc() 它们。
  • 为了避免输入换行符,读取一个字符串,然后使用 sscanf。您可以调用它一次以获取第一个字符,然后根据 char 值调用第二次

标签: c char scanf


【解决方案1】:

你可以使用单个scanf来做到这一点,但是你需要在读取后根据第一个字符解析输入。

char c, alpha[20], tmp[20];
scanf("%c %s %[^\n]\n", &c, alpha, tmp);

//Here 20 is taken for example, size can be anything

然后您可以检查c 的值。如果是c=='c',则需要将tmp拆分为两部分,第一部分是整数,可以通过atoi()函数存储在val中,另一部分是字符串。

如果c=='d' 那么,你只需要将tmp 复制到beta 中就可以了。

【讨论】:

  • 这会调用未定义的行为。 alphatmp 指向任何地方。
  • 为什么在s 中加入"%[^\n]s"
  • @mch 如果您为其分配内存,或者只是创建一个字符数组,它不会给出未定义的行为。这是示例链接:ideone.com/HQoiaN
  • @chux,它允许输入直到找到下一个\n(新行)字符。
  • 你肯定想使用"%c %s %[^\n]\n"。最后那个'\n' 并没有按照你的想法做。更有可能的代码应该使用" %c%s %[^\n]"。为了最好地“清除\n”,请阅读带有fgets()/getline() 的行,然后使用sscanf()
【解决方案2】:
char c, alpha[8], beta[8];
int val;
char line[32];
int state;

fgets(line, sizeof line, stdin);//input by one line
state = sscanf(line, " %c %7s %d %7s", &c, alpha, &val, beta);
if(c == 'd' && state == 3)
    printf ("%c %s %d", c, alpha, val);
else if(c == 'c' && state == 4)
    printf ("%c %s %d %s", c, alpha, val, beta);

【讨论】:

    【解决方案3】:

    我并不是说不能使用scanf() 来完成,但恕我直言,这不是最好的方法。相反,使用fgets() 读取整个like,使用strtok() 对输入进行标记化,然后根据第一个标记值,根据需要遍历输入字符串。

    通用算法看起来像

    1. 使用fgets()读取整行

    2. 使用strtok() 使用空格 ( ) 作为分隔符进行标记。

    3. 获取第一个令牌,将其与所需的输入选项 cd 进行比较。

      注意:不要混淆字符 'c''d'字符串 "c""d"

    4. 基于令牌值,您可以在同一字符串上添加更多对strtok() 的调用以获取输入中剩余数据的值,您可以利用现有的switch-case 方法。一般来说,一直持续到strtok() 返回NULL。

    也就是说,回答你的问题,

    它适用于 d 情况,但在 c 情况下会出现段错误。

    原因是,在当前程序中,您的代码调用了undefined behaviour,因为您使用的是未初始化的指针alphabeta。您需要在使用前为它们分配内存,可能通过malloc() 和家人。

    【讨论】:

      猜你喜欢
      • 2010-11-27
      • 2013-07-12
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      相关资源
      最近更新 更多