if ("test" == "test") // 編譯器可能優化合併,但標準不保證
cout << "相等";
else
cout << "不相等"; // 多數情況輸出此行
"test" 是 const char[5],編譯期分配於 .rodata 區。== 比較的是**地址**,而非內容,故多數情況判定為不相等。strcmp 比較內容#include <cstring>
if (strcmp("test", "test") == 0) // 返回 0 表示相等
cout << "相等";
strcmp(const char*, const char*) 逐字元比較,直到遇到差異或 \0,相等返回 0,否則返回非零值(正/負表示字典序大小)。
strcpy vs memcpy\0 結尾的 C 風格字串 → strcpychar src[] = "test str!";
char dst[15];
strcpy(dst, src); // 包含結束符 \0 自動複製
cout << dst; // 輸出: test str!
src 是陣列,可修改;若寫 char *p = "literal" 則指向唯讀區,**不可**作為 strcpy 目的端。\0 結尾陣列 → memcpyint a[] = {1,2,3,4,5};
int b[5];
memcpy(b, a, sizeof(a)); // 第三參數為位元組數
for (int i=0; i<5; ++i) cout << b[i] << ","; // 1,2,3,4,5,
memcpy(void* dest, const void* src, size_t n) 逐位元組複製 n bytes,不關心內容語意。\0 終止符的場景。memmove。| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
if (str1 == str2) | 比較指標地址 | strcmp(str1, str2) == 0 |
char *p = "abc"; strcpy(p, "def"); | 寫入唯讀區導致崩潰 | char p[] = "abc"; 或 char *p = new char[4]; |
strcpy(dst, src); // dst 未分配空間 | 緩衝區溢出 | 確保 sizeof(dst) > strlen(src)+1 |
memcpy(dst, src, sizeof(src)); // src 是指標 | sizeof 取得指標大小而非資料長度 | 顯式傳遞長度或用 strlen+1 |
std::string:支援 == 直接比較內容,自動管理記憶體,避免上述所有坑。str.c_str() 取得 const char*,strcpy(buf, str.c_str()) 時確保緩衝區足夠。std::vector<uint8_t> 或 std::span (C++20),配合 std::copy 替代 memcpy,型別安全且可檢查邊界。strcmp(或 std::string),切勿用 ==。strcpy 專為以 \0 結尾字串設計;memcpy 適用於任意記憶體塊,需手動指定長度。std::string/std::vector 就別手寫 C 風格字串操作。