輸入一個英文句子 (如 "my name is jorze"),輸出每個單詞在原字符串中的起始下標和結束下標 (或長度)。單詞由字母組成,以空格分隔。
狀態:IN_WORD (正在讀單詞) / OUT_WORD (讀空格)。掃描字符串,記錄狀態變化點。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_LEN 1000
#define MAX_WORDS 100
int main() {
char buf[MAX_LEN];
printf("請輸入英文句子: ");
fgets(buf, sizeof(buf), stdin);
// 移除末尾換行
buf[strcspn(buf, "\n")] = '\0';
int n = strlen(buf);
int wordCount = 0;
int start[MAX_WORDS], end[MAX_WORDS];
int state = 0; // 0=OUT, 1=IN
for (int i = 0; i <= n; ++i) { // 多掃一位處理結尾單詞
char c = (i == n) ? ' ' : buf[i]; // 虛擬結尾空格
if (isalpha((unsigned char)c)) {
if (state == 0) { // 進入單詞
start[wordCount] = i;
state = 1;
}
} else { // 空格或標點
if (state == 1) { // 退出單詞
end[wordCount] = i - 1;
wordCount++;
state = 0;
}
}
}
printf("單詞位置信息:\n");
for (int i = 0; i < wordCount; ++i) {
printf("單詞 %d: 起始=%d, 結束=%d, 內容=\"%.*s\"\n",
i+1, start[i], end[i], end[i]-start[i]+1, buf+start[i]);
}
return 0;
}
| 問題 | 解決方案 |
|---|---|
原回答 buf[i] >= 'a' || buf[i] <= 'z' 恆真 | 改用 isalpha() 或 (c>='a'&&c<='z') || (c>='A'&&c<='Z') |
| 句子結尾無空格導致最後一個單詞未記錄 | 循環至 i <= n,虛擬一個結尾空格觸發狀態轉換 |
| 標點符號處理 | isalpha 自動過濾標點;若需保留撇號如 don't,需自定義判斷 |
| 多字節字符 (中文/UTF-8) | 本題限定英文,單字節處理即可 |
請輸入英文句子: my name is jorze
單詞位置信息:
單詞 1: 起始=0, 結束=1, 內容="my"
單詞 2: 起始=3, 結束=6, 內容="name"
單詞 3: 起始=8, 結束=9, 內容="is"
單詞 4: 起始=11, 結束=15, 內容="jorze"
typedef struct { int start, end; char word[50]; } WordInfo;
WordInfo words[MAX_WORDS];
// 掃描時直接拷貝內容
strncpy(words[wordCount].word, buf+start[wordCount], end[wordCount]-start[wordCount]+1);