2016-12-02 60 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

相關問題