原代碼三大錯誤
char checkcode[63]={...} // ① 缺少分號結尾
// ...
ch[i]=checkcode(m); // ② checkcode 是數組,不是函數,應用下標 [m]
// ...
for(int i=0;i<4;i++) { ... }
ch[i]='\0'; // ③ i 在 for 作用域外不可見,編譯錯誤
修正後完整代碼
#include
#include
#include
int main(void) {
// 1. 字符集:62 個字符 (26小寫+26大寫+10數字)
const char checkcode[] =
"qwertyuiopasdfghjklzxcvbnm"
"QWERTYUIOPASDFGHJKLZXCVBNM"
"0123456789";
char ch[5] = {0}; // 4 字符 + '\0'
srand((unsigned)time(NULL));
for (int i = 0; i < 4; i++) {
int m = rand() % 62; // 0~61
ch[i] = checkcode[m]; // 數組下標訪問
}
ch[4] = '\0'; // 顯式結尾
puts(ch);
return 0;
}
進階改進:避免模數偏差、線程安全、可配置長度
#include
#include
#include
void gen_captcha(char* buf, int len, const char* charset, int charset_len) {
// 拒絕採樣消除模數偏差 (RAND_MAX 可能非 62 倍數)
int limit = RAND_MAX - (RAND_MAX % charset_len);
for (int i = 0; i < len; i++) {
int r;
do { r = rand(); } while (r >= limit);
buf[i] = charset[r % charset_len];
}
buf[len] = '\0';
}
int main(void) {
const char* charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char captcha[7]; // 6 位驗證碼
srand((unsigned)time(NULL));
gen_captcha(captcha, 6, charset, 62);
puts(captcha);
return 0;
}
關鍵知識點總結
| 錯誤類型 | 原代碼 | 修正 | 記憶口訣 |
| 語法 | 數組定義無分號 | 加 `;` | 聲明必結尾 |
| 語義 | 數組名當函數調用 | 改下標 `[index]` | 數組只能下標 |
| 作用域 | 循環變量外部使用 | 提前聲明或用常量 | for(int i) 僅循環內可見 |