2015-07-13 85 views
1

我想在整個我寫的代碼中引用name的輸入,但由於某些原因,在第一個printf()中成功使用它之後,第二個printf()不會打印該名稱。用於char的Scanf輸入一次然後爲空

int main() 
{ 
    char name[50]; 
    char q1[1]; 
    printf(" What is your name?\n"); 
    scanf("%s", name); 
    printf(" Hi %s, Do you want to have some fun? [Y/N]\n",name); 
    scanf("%s",q1); 

    if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0) 
    { 
     printf("Awesome, let's play!\n"); 
    } 
    else 
    { 
     printf("Fine"); goto endgame; 
    } 
    printf("So %s, it's time to get started\n", name); 
    endgame: 
     getchar(); 
    return 0; 
} 

輸出爲入門「尼克是:

尼克嗨,你想有一番情趣?
真棒讓我們玩
所以, 讓我們開始吧

我希望它說:

於是尼克,讓我們開始吧。

但由於某些原因,char name在第一次正確使用後爲空白。

+3

是什麼'q1'限制與scanf()輸入的長度,恰好? –

+1

'scanf(「%s」,name);' - >'scanf(「%49s」,name);' –

+0

我加了'char q1 [50];'它正在爲我工​​作。 – moffeltje

回答

2

擴大您的q1緩衝區的大小。 scanf("%s", q1)沒有足夠的空間來存儲輸入。請記住C使用空字符'\0'來終止字符串。如果你不考慮這個問題,緩衝區可能會溢出到其他內存中,導致undefined behavior。在這種情況下,它可能會覆蓋分配給name的內存,因此name最終會指向「\ 0ick」。這導致printf(%s),它尋找'\0'知道什麼時候停止打印,認爲字符串比實際短。

代碼工作完美,如果你擴大緩衝區:

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

int main(void) 
{ 
    char name[50]; 
    char q1[50]; 
    printf(" What is your name?\n"); 
    scanf("%49s", name); 
    printf(" Hi %s, Do you want to have some fun? [Y/N]\n",name); 
    scanf("%49s",q1); 

    if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0) 
    { 
     printf("Awesome, let's play!\n"); 
    } 
    else 
    { 
     printf("Fine"); 
    } 
    printf("So %s, it's time to get started\n", name); 
    getchar(); 
    return 0; 
} 

輸出:

What is your name? 
Nick 
Hi Nick, Do you want to have some fun? [Y/N] 
y 
Awesome, let's play! 
So Nick, it's time to get started 

請注意,我已經添加了預選賽%49s避免緩衝區溢出這樣的。


你也可以完全通過改變char q1[50]scanf("%49s")簡單char q1scanf("%c%*c", &q1)(注意操作員「的地址」,因爲q1不再是一個指針)規避另一個字符串的需要。

你甚至可能會從中獲得性能上的提升(儘管很小),因爲字符串是臭名昭着的內存佔用者。比較單個字符通常比比較字符串更受歡迎。

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

int main(void) 
{ 
    char name[50]; 
    char q1; 
    printf(" What is your name?\n"); 
    scanf("%49s%*c", name); 
    printf(" Hi %s, Do you want to have some fun? [Y/N]\n",name); 
    scanf("%c%*c",&q1); 

    if(q1 == 'Y' || q1 == 'y') 
    { 
     printf("Awesome, let's play!\n"); 
    } 
    else 
    { 
     printf("Fine"); 
    } 
    printf("So %s, it's time to get started\n", name); 
    getchar(); 
    return 0; 
} 
    if(q1 == 'Y' || q1 == 'y') 
    { 
     printf("Awesome, let's play!\n"); 
    } 
    else 
    { 
     printf("Fine"); 
    } 
    printf("So %s, it's time to get started\n", name); 
    getchar(); 
    return 0; 
} 

如果你走這條路,你必須忽略使用格式說明%*c因爲按回車發送一個關鍵流和回車鍵。

4

問題,(如我正確假定)是具有char q1[1];,然後用它像

scanf("%s",q1); 

它使存儲器邊界溢出,因爲,一字符數組不足以保持只有一個元素的字符串,因爲它缺少字符串所需的空終止符的空間。這調用undefined behaviour

相反,

  • 變化char q1[1];char q1;
  • 變化scanf("%s",q1);scanf(" %c", &q1);
  • 變化if(strcmp(q1,"Y") == 0||strcmp(q1,"y")==0)if((q1 =='Y') || q1 == 'y')

這就是說,作爲一個音符,

  1. 推薦的簽名main()int main(void)
  2. 爲了避免緩衝區溢出的可能性由不再輸入(S),最好寫像

    scanf("%49s", name); 
    
相關問題