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

C 語言單詞統計程序調試:for 循環邏輯錯誤導致輸入處理失效的根因分析與修正

     編輯:程式設計疑難解答

C 語言單詞計數程序核心邏輯錯誤深度剖析

初學者編寫單詞統計程序時,常因循環變量初始化順序錯誤、字符讀取邏輯缺陷導致程序無法正確處理輸入。本文通過一個典型錯誤案例,逐行剖析問題根因,提供修正版代碼並講解核心知識點。

原始錯誤代碼逐行分析

#include <stdio.h>
int main() {
    int ch, i, count = 0, flag = 0;
    char bb[1000];
    printf("please input some words:");
    gets(bb);              // 危險函數,已棄用
    ch = bb[i];            // 【錯誤1】i 未初始化,訪問 bb[i] 行為未定義
    for (i = 0; ch != '\0'; i++) {  // 【錯誤2】循環條件使用舊 ch,未在循環內更新
        if (ch == ' ') flag = 0;
        else if (flag == 0) { count++; flag = 1; }
    }
    printf("單詞個數為%d", count);
}

三大核心錯誤詳解

  1. 變量未初始化:int i; 未賦值,ch = bb[i] 讀取隨機內存地址,導致未定義行為。
  2. 循環邏輯斷層:ch 在循環外賦值一次,循環內從未更新,導致要么不進循環,要么死循環,完全脫離輸入數據。
  3. 使用危險函數:gets() 不檢查緩衝區邊界,極易造成緩衝區溢出,C11 標準已移除,必須改用 fgets()。

修正版代碼(含詳細註釋)

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

int main() {
    char bb[1000];
    int count = 0, flag = 0;
    
    printf("please input some words: ");
    // 安全讀取:指定最大長度,自動處理換行符
    if (fgets(bb, sizeof(bb), stdin) == NULL) return 1;
    
    // 遍歷字符串每個字符
    for (int i = 0; bb[i] != '\0'; i++) {
        char ch = bb[i];  // 關鍵:在循環內獲取當前字符
        
        if (ch == ' ' || ch == '\t' || ch == '\n') {
            flag = 0;  // 遇到分隔符,重置標誌
        } else if (flag == 0) {
            count++;   // 發現新單詞首字符
            flag = 1;  // 設置標誌,跳過單詞後續字符
        }
    }
    
    printf("單詞個數為 %d\n", count);
    return 0;
}

核心算法思想:有限狀態機

程序維護一個二狀態變量 flag:

  • flag = 0:當前處於「非單詞內」(分隔符或開頭)
  • flag = 1:當前處於「單詞內」

狀態轉移:分隔符 → 置 0;非分隔符且 flag=0 → 計數+1、置 1;非分隔符且 flag=1 → 保持。這是處理字符流分詞的經典模式,廣泛用於詞法分析。

進階擴展

  • 支持多種分隔符:空格、制表符、換行符、標點符號(strchr(" \t\n.,;!?", ch))
  • 統計單詞長度分布、最長單詞、詞頻(需引入哈希表/字典樹)
  • 處理 UTF-8 多字節字符:需按字節解碼後再判斷
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved