【问题标题】:How to scanf full sentence in C如何在C中扫描完整的句子
【发布时间】:2013-09-04 00:22:08
【问题描述】:

如何在不使用fgets()gets()的情况下在C语言中scanf()完整句子

我想扫描用户的命令行并根据第一个单词识别命令。 例如: mkdir

所以我需要认识到用户想要创建一个名为“dir_name”的新目录。

我的代码:

int main(){
  char *ch=malloc(sizeof("50");
  while (strcmp(ch,"exit")!=0){
     scanf("%[^\n]",ch);
  } 

当我在输入第一句话并按回车后运行此代码时,它进入了无限循环,我不知道为什么?

【问题讨论】:

  • 你为什么不想使用fgets?使用它读取整行然后sscanf 稍后解析行听起来更容易。

标签: c string scanf


【解决方案1】:

你的问题很可能在这里:

char *ch=malloc(sizeof("50");

首先,您缺少一个右括号。但是假设这是发布问题而不是您的实际代码中的错字,则存在更深层次的问题。

"50" 在双引号内是一个字符串文字。当sizeof() 应用于字符串文字时,您将获得字符串中的字符数,包括终止NUL。所以你只为ch 中的三个字符分配空间。

当您尝试scanf() 输入时,您正在写入超过三字符缓冲区ch 的末尾。省略sizeof(),简单地说:

char* ch = malloc (50);

此外,扫描集 %[^\n] 确实跳过前导空格。您的第一个 scanf() 将停在换行符处,该换行符将保留在缓冲区中。 while 循环中的后续 scanf() 调用将遇到该换行符并尽职地停止,因为它已从您的扫描集中排除。所以循环条件

while (strcmp (ch, "exit"))

永远不会变成真的,你会得到一个无限循环。在scanf() 之后使用换行符来避免这个问题:

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

%*c 的意思是“读取一个字符然后丢弃它”。所以它将读取留在缓冲区中的\n,然后不会将其保存在任何地方。因此,您的下一个scanf() 不会在缓冲区的开头遇到\n,您的程序将按您的意愿运行。

【讨论】:

  • 谢谢,它现在可以工作了 :) 这就是问题所在:“scanf ("%[^\n]%*c", ch);" “%*c”是什么意思?再次感谢
  • 最好使用scanf ("%49[^\n]%*1[\n]", ch);来限制输入,并且只用长线折腾'\n'。如果输入是"\n",即使这样也不会读取任何内容,因为它会在stdin 中留下'\n'。建议fgetc()。然而,这个答案很好地解决了 OP 的主要问题。
【解决方案2】:
#include<stdio.h>
int main()
{
    char  input_string[100];
    scanf("%[^\n]s",&input_string);
    printf("Hello ,world.\n");
    printf("%s",input_string);
    return 0;
}

【讨论】:

  • 嗨,这可能很好地解决了问题......但如果你能编辑你的答案并提供一些关于它的工作原理和原因的解释会很好:)不要忘记 - 那里在 Stack Overflow 上是一堆新手,他们可以从你的专业知识中学到一两件事——对你来说显而易见的事情对他们来说可能不是。
【解决方案3】:

scanf("%[^\n]s",s);这样你也可以使用 scanf("%[^\n]%*c", s);其中 s 定义为 char s[MAX_LEN] 其中 MAX_LEN 是 s 的最大大小。这里,[] 是扫描集字符。 ^\n 代表在没有遇到换行之前接受输入。然后,使用这个 %*c,它读取换行符,这里使用的 * 表示这个换行符被丢弃。

【讨论】:

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