为什么我的程序在使用scanf后暂停?

时间:2016-12-02 05:49:05

标签: c cmd scanf

#include<stdio.h>
#include<stdlib.h>

int main()
{
    char *userInput;
    userInput = (char*)malloc(sizeof(userInput));

    printf("Commands:\n");
    printf("\ta name - adds given name to list\n");
    printf("\tr name - removes given name from list\n");
    printf("\tp      - prints out list\n");
    printf("\te      - exits\n");

    printf("\n\nEnter a command: ");
    scanf("%s\n",userInput);
    printf("\nThe user input was: %s\n", userInput);

    return 0;
}

我编译代码“gcc -std = gnu99 -m32 -Wall -g -o namelist namelist.c” 每当我运行可执行文件时,都会显示所有第一个printf,并在输入时得到提示。每当我输入一个输入并按回车键时,在我输入另一个输入之前,我都没有得到下一个printf的提示。

This is what is looks like when I run the program

4 个答案:

答案 0 :(得分:1)

字符(char)或字符集char*)来自stdin scanf类似函数\n(输入结果)键推)保留在缓冲区中。因此,在下一次输入之前,程序应该清除\n以及输入缓冲区中可能存在的所有其他混乱(例如,在输入错误的数字后,例如12asw - scanf需要{{ 1}}并在缓冲区中留下12

请考虑以下示例并注意,我建议使用asw\n

clnInpBuf()

<强>更新

“命令处理器”的

模板可以是:

#include <stdio.h>

void clnInpBuf()
{
    char c;
    while ((c = getchar()) != '\n' && c != EOF);
}

int main(void)
{
    char str[10];
    char ch;
    scanf("%c", &ch);
    fflush(stdin); // in some cases that works for input stream 
                   // (but fflush is better to use only for output streams)
    scanf("%9s", str);
    clnInpBuf(); // this works always
    printf("char was %c.\n", ch);
    printf("string was %s.\n", str);
}

答案 1 :(得分:0)

只需取出

中的“\ n”即可
SELECT Year , ID , Amount 
FROM #Table T1
JOIN
(
  SELECT MAX(Amount) Amount,Year
  FROM #Table
  GROUP BY Year
) A ON A.Year = T1.Year AND A.Amount = T1.Amount

答案 2 :(得分:0)

仔细阅读 scanf(3)。请注意,对于gcc -m32sizeof(userInput)等于4(所有指针的大小相同;没有-m32则为8)。因此,如果用户输入类似working的内容(或任何四个字符或更多字符的输入,而不只是a之类的一个字母),则表示您undefined behavior(因为buffer overflow })那真的是bad。您可能应该考虑使用getline(3)代替(或者甚至readline(3)),例如

char* userInput=NULL;
size_t sizeInput= 0;
printf("Commands:\n");
/// put your other printfs here, then
ssize_t lengthInput = getline(&userInput, &sizeInput, stdin);
if (lengthInput < 0 || userInput==NULL)
  { perror("input error"); exit(EXIT_NULL); };

现在您在userInput中有完整的输入行(包括终止换行符),并且您知道其长度为lengthInput。您可parse该行,可能使用sscanf(3)(提示:使用其返回计数,并考虑使用%n)或仅使用其他技术(某些strcmp或{{ 3}} ...)。完成后,您应该free(userInput)

请注意scanf(或sscanf)不为分析的数据分配任何内存,除非您使用%ms(可能是POSIX特定的)。对于%s,它总是期望一些固定长度的缓冲区,对于声明为char buf[64];数组缓冲区,您最好使用%63s给出大小;顺便说一句,你应该总是测试scanf的结果数。所以你可能会编码(在上面之后)

char nambuf[64];
if (sscanf(userInput, "a %63s", nambuf)==1) {
 // use nambuf to add it
}
else if (sscanf(userInput, "r %63s", nambuf)==1) {
 // use nambuf to remove it
} 

(但上面有点傻,我们读取一个任意大小的行,但最多63个字节的进程nambuf)。您可以使用scanf之类的if (scanf("a %63s", nambuf)==1),而无需任何userInput

或者,您可以使用特定于Linux的%as或更好的POSIX特定%ms,如:

char* nameptr=NULL;
if (scanf("a %ms", &nameptr)==1) { 

然后成功的scanfmalloc - 编辑并填充nameptr,您应该稍后free(nameptr)。如果您只想接受小写字母,请考虑使用if (scanf("a %m[a-z]", &nameptr)==1)等编码...

答案 3 :(得分:0)

当userinput是指针时,此语句将分配4个字节的数据。     userInput =(char *)malloc(sizeof(userInput));

如上面的答案所指出的,当字符串大小超过3个字节时,这将导致缓冲区溢出。

我也会在读取字符串

时建议使用scangets上的fgets()

示例代码 -

  #include <stdio.h>
  #include <stdlib.h>


   int main() {
      // your code goes here
     char *userinput = (char *)malloc(100);
     fgets(userinput,100,stdin);
     printf("%s",userinput);
     return 0;
}