2016-09-12 81 views
-1

每當我聲明一個變量爲char並將其掃描爲字符串「%s」時,我的輸出控制檯崩潰。下面是代碼代碼塊輸出控制檯已停止工作

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <string.h> 
int main() 
{ 
    char a[20]; 
    int i; 
    printf("Enter a name "); 
    scanf("%s",&a); 
    for(i=0;i<strlen(a);i++) 
    { 
     a[i] = toupper(a[i]); 
     i++; 
     printf("%s\n",toupper(a[i])); 
    } 
    return 0; 
} 
+0

'的scanf( 「%S」,&a);' - >'的scanf( 「%19S」,&a);'' –

回答

2

第二i++;for循環體內部可能會導致索引以指向斷接一個然後,printf("%s\n",toupper(a[i]));會出綁定訪問它調用undefined behavior

您可以從循環體內部刪除i++

接下來,toupper(a[i])返回一個int,這對格式說明符%s無效,該格式說明符再次調用UB。

這就是說,

  • ,以防止緩衝區溢出過度長的輸入,最好限制輸入長度scanf()

  • 你並不需要傳遞一個數組的地址,只是數組名就足夠了

因此,總體而言,你應該寫

scanf("%19s",a); 
+0

scanf的( 「%19S」,&a);'應該是'的scanf( 「%19S」,A); '。 – mch

+0

@mch感謝,指出。:) –

+0

非常感謝:),順便說一句這段代碼的輸出是假設BA一定的規律,如果字符串輸入的,早上,預期產出應該是上午 上午 上午 上午 上午 MORNINg 早上好 –

1

在使用toupper並打印的循環中有兩個問題。

首先是你在循環中遞增變量i兩次

的第二個問題是printf

printf("%s\n",toupper(a[i])); 

在這裏,你問printf打印字符串,但作爲參數,你給它一個字符(實際上是一個inttoupper返回int)。使用"%c"格式說明符打印單個字符。

順便說一句,打印時不需要撥打toupper,因爲前面的賦值,字符應該已經是大寫字母。

0

您的打印循環是錯誤表現與給你未定義行爲:

printf("%s\n",toupper(a[i])); 

被傳遞到toupper(a[i])printf()%s格式說明,這需要一個char *不是普通char。這觸發了未定義的行爲。

有沒有點打印每一個字符一個接一個,而不是整個字符串轉換爲大寫,然後再打印一次:有時需要

for(i = 0; a[i] != '\0'; ++i) 
{ 
    a[i] = (char) toupper((unsigned char) a[i]); 
} 
printf("%s\n", a); 

各地toupper()的強制轉換,因爲它需要和返回int,你想在轉換/轉換字符的時候有點小心。

請注意,我將strlen()的調用作爲因素考慮在內,這可能有點「太聰明」,但我希望這段代碼能夠寫出來。如果我們要循環字符,則不需要分別計算長度。