strchr 庫函數與手動掃描兩種解法對比題目要求:輸入一行長度 ≤ 80 的字符串,再輸入一個字符 c,在字符串中查找 c 首次出現的位置。若找到,輸出從該位置到末尾的子串;否則輸出 Not found。區分大小寫。
#include#include #define MAX 80 int main() { char str[MAX + 1]; char c; // 讀取整行字符串(含空格) fgets(str, sizeof(str), stdin); str[strcspn(str, "\n")] = '\0'; // 移除換行符 // 讀取查找字符(跳過可能殘留的換行符) scanf(" %c", &c); // 格式串前加空格跳過空白字符 // strchr 返回首次出現位置指針,未找到返回 NULL char *pos = strchr(str, c); if (pos) { puts(pos); // 直接輸出從 pos 到末尾的字符串 } else { printf("Not found\n"); } return 0; }
關鍵點:scanf(" %c", &c) 中的前導空格會跳過緩衝區中殘留的 \n、空格等空白字符,直接讀取下一個可見字符,避免誤讀換行符。
#include#include #define MAX 80 void find_and_print(char *s, int len, char c) { for (int i = 0; i < len; i++) { if (s[i] == c) { puts(s + i); // s+i 是第 i 個字符的地址,puts 輸出以此為起始的字符串 return; } } printf("Not found\n"); } int main() { char str[MAX + 1]; char c; fgets(str, sizeof(str), stdin); str[strcspn(str, "\n")] = '\0'; scanf(" %c", &c); find_and_print(str, strlen(str), c); return 0; }
fgets` vs gets` vs scanf("%s")`| 函數 | 讀取範圍 | 緩衝區保護 | 保留換行符 | 推薦度 |
|---|---|---|---|---|
fgets(buf, n, stdin) | 整行(含空格) | 是 (n-1) | 是 | ★★★★★ 標準安全 |
gets(buf) | 整行 | 否 (已棄用 C11 移除) | 否 | ☆☆☆☆☆ 危險 |
scanf("%s", buf) | 單詞(跳過空白) | 否 (無長度限制) | 否 | ★★☆☆☆ 僅適合單詞 |
strchr` 內部原理// 簡化版實現
char *my_strchr(const char *s, int c) {
while (*s) {
if (*s == (char)c) return (char *)s;
s++;
}
return (c == '\0') ? (char *)s : NULL; // 查找 \0 時返回結束符地址
}
puts(s+i)` 等價於 printf("%s\n", s+i)`puts 自動追加換行符,性能略優於 printf。s+i 是指針算術:字符數組名 s 退化為指向首元素指針,+i 偏移 i * sizeof(char) 字節。題目要求區分大小寫,strchr 和直接比較 == 均區分大小寫(ASCII 碼不同)。若需忽略大小寫,可用 strcasestr (POSIX) 或自行 tolower 比較。
| 輸入字符串 | 查找字符 | 輸出 | 說明 |
|---|---|---|---|
It is a black box | b | black box | 首個 'b' 在 "black" |
It is a black box | B | Not found | 大小寫不同 |
Hello World | o | o World | 首個 'o' 在 "Hello" |
Test | x | Not found | 不存在 |
Space test | (空格) | test | 查找空格字符 |
void find_all(char *s, char c) {
int found = 0;
for (int i = 0; s[i]; i++) {
if (s[i] == c) {
printf("位置 %d: %s\n", i, s + i);
found = 1;
}
}
if (!found) printf("Not found\n");
}
總結:字符串查找是 C 語言基礎操作核心。掌握
fgets安全讀行、scanf(" %c")吃掉空白讀字符、strchr標準庫查找、指針算術 s+i截取子串、puts輸出,即可解決所有單字符查找變體。工程中優先使用標準庫,手動循環僅用於教學理解或極特殊定制需求(如查找第 k 次出現)。