2016-12-02 174 views
0
#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.c” 每当我运行所有的第一个printf被显示在可执行文件和我得到提示上的输入。每当我输入的输入,然后按回车,我没有得到提示未来的printf直到我把另一个观点。。为什么我的程序在使用scanf后暂停?

This is what is looks like when I run the program

+0

使用'gdb'调试运行一步程序一步 -

也读字符串

示例代码时,我会建议在scanf函数与fgets()。 –

+1

欢迎来到Stack Overflow! [请参阅此讨论,为什么不在'C'中投射'malloc()'和family的返回值。](http://stackoverflow.com/q/605845/2173917)。 –

+2

提示:'\ n'用于回车。您是否在https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm中看到任何'\ n'?的[scanf函数] –

回答

0

只要采取了“\ n”在您的

scanf("%s\n",userInput) 
+0

OMG非常感谢你这是逼我疯了 – Programmer

+0

那么您有超过4个字节,例如任何输入缓冲区溢出'foobar' –

+0

@BasileStarynkevitch我相信,输入超过3个字符('\ 0'的最后一个字符)发生缓冲区溢出。这个:'malloc(sizeof(char *)) - 1'确切地说。 – babon

0

仔细阅读scanf(3)。注意,gcc -m32你有sizeof(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)或者只使用其他技术(某些strcmpstrtok(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) { 

那么成功scanf将有malloc -ed和充满nameptr建议您稍后free(nameptr)。如果你想只接受小写字母考虑编码类似if (scanf("a %m[a-z]", &nameptr)==1)等...

1

虽然字符(char)或字符集(char*)从stdin未来具有相似功能的scanf Enter键推\n(结果)保持在缓冲区中。因此,下输入前程序应该清除该\n以及所有其他的混乱,可以在输入缓冲区(如12asw例如后不正确输入数字, - scanf需要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); 
} 

UPDATE:

为贵 “的命令处理器” 模板可以是:

int main(void) 
{ 
    char name[21]; 
    char command; 
    while (1) 
    { 
     scanf("%c", &command); 
     clnInpBuf(); 
     switch (command) 
     { 
     case 'a': 
     case 'r': scanf("%20s", name); 
        clnInpBuf(); 
        printf("Command was:\n%c %s\n", command, name); // if ('a'==command) addRecord(name); else removeRecord(name); 
        break; 
     case 'p': // TODO: add output 
        break; 
     case 'e': return 0; 
        break; // this is not realy needed 
     default: 
        printf("Wrong command\n"); 
     } 

    } 
} 
+0

'fflush(标准输入)'是*错*,你只能'fflush'的*输出流*或'NULL' –

+0

@BasileStarynkevitch是的,你说得对!...但我确实在某些情况下,写下了”那( fflush)的作品”和‘我推荐使用clnInpBuf()’ – VolAnd

0

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

由上述答案指出,这将导致缓冲区溢出当字符串大小大于3个字节。

#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; 
} 
+0

你给的唯一附加信息是使用'fgets'的建议。但是,你需要提供更多的代码。 –

+0

为fgets添加了示例代码 – hariudkmr

相关问题