【问题标题】:Issues ignoring spaces with scanf when using multiple scanf's in C在 C 中使用多个 scanf 时使用 scanf 忽略空格的问题
【发布时间】:2014-08-18 23:46:12
【问题描述】:

我试图在一个小程序中多次使用scanf 来获取保证有空格的输入。从我浏览过的多个线程来看,scanf("%[^\n]", string); 似乎是让它忽略空格的方法。这适用于一行,但该行之后的任何其他 scanf 都不会通过,并且它们各自的字符串会输出以下内容:

Action: J���J
 Resolution: J:F�J�B�J

下面是一些我认为可行的示例代码,但没有。

#include <stdio.h>

int main(void)
{   
    char str1[100];
    char str2[100];

    printf("Situation?\n");
    scanf("%[^\n]", str1);

    printf("Action Taken?\n");
    scanf("%[^\n]", str2);

    printf("Situation: %s\n",str1);
    printf("Action: %s\n",str2);
}

如果我在提示情况时输入“只是一个测试”,则会发生以下情况:

Situation?
just a test
Action Taken?
Situation: just a test
Action: ��_��?�J.N=��J�J�d�����J0d���8d��TJ�J

有什么建议或解决方案(不包括fgets)?对正在发生的事情进行解释也很好。

编辑:解决方案在scanf: "%[^\n]" skips the 2nd input but " %[^\n]" does not. why?

添加char* fmt = "%[^\n]%*c"; 100% 有效。

char* fmt = "%[^\n]%*c";

  printf ("\nEnter str1: ");
  scanf (fmt, str1);
  printf ("\nstr1 = %s", str1);

  printf ("\nEnter str2: ");
  scanf (fmt, str2);
  printf ("\nstr2 = %s", str2);

  printf ("\nEnter str3: ");
  scanf (fmt, str3);
  printf ("\nstr2 = %s", str3);

  printf ("\n");

【问题讨论】:

  • [ 说明符必须找到至少 1 个字符,否则匹配失败。你会发现scanf在这种情况下返回0(你应该总是检查scanf的返回值)然后你使用未初始化的变量str2导致未定义的行为。

标签: c string scanf


【解决方案1】:

改变

scanf("%[^\n]", str1);

scanf("%[^\n]%*c", str1);//consume a newline at the end of the line

【讨论】:

    【解决方案2】:

    方法数:

    而不是以下不消耗 Enter'\n'(这是问题):

    scanf("%[^\n]",str1);
    
    1. 使用尾随的换行符。 "%*1[\n]" 只会消耗 1 个 '\n',但不会保存。

      scanf("%99[^\n]%*1[\n]" ,str1);
      
    2. 在下一个 scanf() 上使用尾随换行符。 " " 占用前面和前导的空白。

      scanf(" %99[^\n]", str1);
      
    3. 使用fgets(),当然,这不是scanf()。最好的方法。

      fgets(str1, sizeof str1, stdin);
      

    无论哪种解决方案,限制读取的最大字符数并检查函数的返回值。

        if (fgets(str1, sizeof str1, stdin) == NULL) Handle_EOForIOError();
    

    【讨论】:

    • 一个问题:为什么要加99
    • @Tony 99 限制扫描并存储在str1 中的字符数(宽度)。在存储了多达 99 个char 之后,附加了 `\0'。
    • 谢谢。我以为99 会是这里的一些特殊号码,我可以使用其他号码。
    • @Tony 与其他 scanf() 说明符一样,"%5d" 表示最多扫描 5 个字符,因此可以扫描和保存值 -9999 到 99999。这里的 99 是 str1[100] 的宽度参数。
    • 感谢您的耐心等待。
    【解决方案3】:

    对于你的问题我没有直接的答案,如果你想要一行输入,为什么不直接使用fgets(甚至gets)?

    【讨论】:

      【解决方案4】:

      解决方案一:使用scanf

      如果你还想看scanf的话,@chux 和@BLUEPLXY 提供的答案就够了。喜欢:

       scanf(" %[^\n]", str);  //notice a space is in the formatted string
      

       scanf("%[^\n]%*c", str);
      

      解决方案二:使用getline()(虽然是POSIX扩展)

      Because using gets() and 'fgets()` are unreliable sometimes.

      【讨论】:

        猜你喜欢
        • 2021-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多