2013-08-17 61 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef char* string; 

int main(void) 
{ 
    char *names[6]; 
    int num_entries = 0,i=0,size=0; 
    string name = (string) malloc(sizeof(char) * 16); 

    printf("\nHow many names do you want to enter ? \n"); 
    scanf("%d",&num_entries); 

    for(i=0 ; i < num_entries ; i++) 
    { 
     printf("\nEnter a name : "); 
     gets(name); 
     size = strlen(name); 
     names[i] = (string) malloc(sizeof(char)*size + 1); 
     strcpy(names[i],name); 
    } 

    for(i=0 ; i < num_entries ; i++) 
     puts(names[i]); 

} 

第一次在這個程序中的字符串沒有被讀取周圍循環的第一時間,但是能正常工作的所有後續調用,程序只需簡單的接受N個字符串,存儲和顯示他們。但它執行n-1次。解決方案也可以隨意指出指針,分配等方式中的任何錯誤,任何反饋都會被讚賞。字符串沒有被讀取周圍

+2

'gets()'是邪惡的。考慮使用'fgets()'來代替。查看本頁底部附近的BUGS部分:http://manpages.debian.net/cgi-bin/man.cgi?query=fgets&apropos=0&sektion=0&manpath=Debian+7.0+wheezy&format=html&locale=en – alk

+0

更改了獲取()調用fgets(name,16,stdin)仍然是bug – rootavish

+0

@alk只是對改進做出評論,而不是提供對問題的回答。這就是爲什麼它是評論,而不是答案。 :)這是另一個評論:因爲你總是設置它們,所以你的整數預初始化程序是多餘的。 :) – lurker

回答

2

呼叫gets在循環之前丟棄scanf左邊的新行。

或者更好的是,使用標準的解決方法丟棄未讀輸入:

int c; 
while ((c = getchar()) != '\n' && c != EOF); 
+0

'char c; \t \t while((c = getchar()!='\ n')&& c!= EOF) \t \t {name [i] = c; \t \t i ++; } \t \t name [i] ='\ 0'; 「這樣的事情? – rootavish

+1

@ superuser47,'getchar'返回一個'int',所以'int c'就像Anthony所說的那樣。他的建議只是用它來吞噬字符,直到下一行換行。如果你想改變你的代碼來使用它作爲閱讀'name'的機制,那麼如果你對它有更多的問題,那麼把它作爲你的原始文章的編輯來展示是很好的。 – lurker

+0

超級用戶,您誤認了代碼的意圖。在scanf(「%d」,&num_entries);'之後並且在循環之前使用它 - 放棄換行符。 –

2

這裏的問題,這是典型的scanf聲明的是,當你進入它不使用換行符你想要的名字的數量並按下「輸入」。

因此,換行符停留在標準輸入緩衝區中,直到您執行下一次讀取,在這種情況下,這是您嘗試讀取的第一個名稱,因此您的名字只是「換行符」。爲了解決這個問題,請使用getchar()來消化換行符,這樣就不會再有這個問題了。

通常,根據經驗法則,您幾乎總是希望在scanf聲明後使用getchar()或類似的語句來處理此問題。

我修改了下面的代碼,對我來說工作正常。由於某些行不是必需的,我也清理了一下。

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

typedef char* string; 

int main(void) 
{ 
    string names[6]; 
    int num_entries=0, i=0; 
    string name = malloc(sizeof(char) * 16); 

    printf("\nHow many names do you want to enter ? \n"); 
    scanf("%d",&num_entries); 
    getchar(); 
    for(i=0 ; i < num_entries ; i++) 
    { 
     printf("\nEnter a name : "); 
     fgets(name,16,stdin); 
     names[i] = malloc(sizeof(char)*strlen(name) + 1); 
     strcpy(names[i],name); 
    } 

    for(i=0 ; i < num_entries ; i++) 
     puts(names[i]); 
return 0; 
} 
+0

既然你已經聲明瞭一個字符串typedef,你可以使用'string names [6]'而不是'char * names [6]'。至於'fgets',它會阻止你對16個字符的有限字符串大小進行溢出。 – xt454

1

下面是帶有所有建議的代碼。請注意,Anthony Accioly因答案而獲得獎勵。

int main(void) 
{ 
    char *names[6]; 
    int num_entries = 0, i = 0, size = 0, c = 0; 
    string name = malloc(sizeof(char) * 16); 

    if (!name) 
    { 
     printf("Unable to allocate memory for name\n"); 
     return(1); 
    } 

    printf("\nHow many names do you want to enter ? \n"); 
    scanf("%d",&num_entries); 
    while ((c = getchar()) != '\n' && c != EOF); 

    for(i = 0 ; i < num_entries; i++) 
    { 
     printf("\nEnter a name : "); 
     gets(name); 
     size = strlen(name); 
     names[i] = (string) malloc(sizeof(char)*size + 1); 
     strcpy(names[i],name); 
    } 

    for(i=0 ; i < num_entries ; i++) 
     puts(names[i]); 

    return(0); 
} 
0

您還可以使用fflush(stdin);作爲替代getchar()while(...)聲明。

P.S .:我很抱歉在這裏寫下我的建議,因爲我沒有足夠的評論聲望。