首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言字符數組賦值與輸出詳解:從scanf到逐字符處理

     編輯:C 語言問答

問題背景

在C語言學習初期,許多初學者會遇到字符數組賦值與輸出的困惑。典型場景:定義char a[10]未初始化,使用scanf("%s", a)輸入字符串"1111000010",卻發現輸出時a[0]打印整個字符串,a[1]從第二個字符開始打印,以此類推。本文將深入解析原因並提供正確解決方案。

核心問題分析

1. 為什麼scanf不需要&符號?

數組名a本身就是首元素地址,等價於&a[0]。scanf("%s", a)中%s期望接收字符指針,直接傳遞數組名即可。若加&a則類型不匹配(char (*)[10] vs char*),雖然某些編譯器可能勉強工作,但語義錯誤。

2. 為什麼輸出呈現"遞減"現象?

關鍵在於printf("%s", a[i])的誤用。%s期望char*參數,但a[i]是char類型(單個字符)。編譯器將字符值作為地址解讀,導致從該字符對應的ASCII碼地址開始打印,直至遇到\0。實際上:

  • a[0] = '1' (ASCII 49),printf("%s", 49)嘗試從地址49讀取字符串
  • a[1] = '1' 同理

觀察到的"遞減"現象純屬巧合,屬於未定義行為。

正確解決方案

方案一:逐字符輸入(推薦用於進制轉換)

char a[10];
for(int i = 0; i < 10; i++) {
    scanf(" %c", &a[i]);  // 注意%c前的空格過濾換行符
}

方案二:字符串輸入後逐字符處理

char str[11];  // 留空間存儲\0
scanf("%10s", str);  // 限制長度防止溢出
for(int i = 0; str[i]; i++) {
    a[i] = str[i] - '0';  // 轉換為數值 0/1
}

方案三:直接處理字符串進行進制轉換

char binary[33];
scanf("%32s", binary);
long decimal = 0;
for(int i = 0; binary[i]; i++) {
    decimal = decimal * 2 + (binary[i] - '0');
}
printf("%ld", decimal);

關鍵知識點總結

  1. 數組名 vs 地址:數組名在表達式中自動轉換為首元素指針,scanf("%s", a)正確,scanf("%s", &a)類型不匹配
  2. %s 與 %c 的區別:%s讀取字符串(遇空白停止),%c讀取單字符(含空白)
  3. 字符與數值轉換:'0'~'9'對應ASCII 48~57,ch - '0'得數值
  4. 緩衝區處理:scanf(" %c", ...)中空格可跳過殘留換行符

進制轉換完整示例

#include 
#include 

int main() {
    char binary[33];
    printf("請輸入二進制數: ");
    scanf("%32s", binary);
    
    long decimal = 0;
    for(int i = 0; binary[i]; i++) {
        if(binary[i] != '0' && binary[i] != '1') {
            printf("非法輸入!\n");
            return 1;
        }
        decimal = decimal * 2 + (binary[i] - '0');
    }
    printf("十進制結果: %ld\n", decimal);
    return 0;
}

掌握字符數組與字符串的本質區別,正確使用輸入輸出格式符,是C語言進階的基石。建議多練習字符處理相關題目,深化理解。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved