首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C/C++ 字串常量比較陷阱與正確複製策略

     編輯:VC 教學

驚人的現象:字串常量 == 字串常量 可能為假


if ("test" == "test")  // 可能輸出「不相等」!
    cout << "相等";
else
    cout << "不相等";

根本原因

  • 字串常量存放在**唯讀資料段**,每個出現位置**可能**分配獨立地址(編譯器可選擇合併相同常量,但標準不保證)。
  • == 比較的是**指標地址**,而非字串內容。

正確比較:strcmp / std::string


// C 風格
#include <cstring>
if (strcmp("test", "test") == 0)  // 返回 0 表相等
    cout << "相等";

// C++ 風格(推薦)
#include <string>
if (std::string("test") == "test")  // 內容比較
    cout << "相等";
// 或直接
if (std::string_view("test") == "test")  // C++17 零複製視圖比較

字串複製:strcpy vs memcpy

函式適用對象終止條件備註
strcpy(dest, src)以 \0 結尾的 C 字串複製含 \0 為止目標空間必須足夠,否則緩衝區溢位
strncpy(dest, src, n)同上複製 n 字元,不足補 \0若 src 長度 ≥ n,結果**不含 \0**,需手動補齊
memcpy(dest, src, n)任意記憶體區塊(含 \0 內嵌)精確複製 n 位元組不關心 \0,適用二進位資料、結構體複製

程式範例


char src[] = "test str!";
char dest[15];
strcpy(dest, src);          // 正確複製含結束符
cout << dest << endl;

int a[] = {1,2,3,4,5};
int b[5];
memcpy(b, a, sizeof(a));    // 複製整個陣列位元組
for (int i=0;i<5;++i) cout << b[i] << ',';

常見錯誤與避坑

  • 用指標賦值複製字串:char* p = "hello"; char* q; q = p; → 複製指標,非內容。修改 *q 會崩潰(修改唯讀段)。
  • strcpy 目的緩衝區過小:永遠確保 sizeof(dest) > strlen(src),或用 strncpy + 手動加 \0。
  • memcpy 重疊區域:來源與目標重疊行為未定義 → 用 memmove。
  • 字串常量修改:char* p = "test"; p[0] = 'T'; → 未定義行為(段錯誤)。正確:char p[] = "test"; 或 std::string。

現代 C++ 最佳實踐

  1. 預設使用 std::string:自動管理記憶體、支援 == 比較、+ 拼接、substr 切片、編碼轉換。
  2. 唯讀視圖用 std::string_view (C++17):零複製、支援比較/查找、不擁有記憶體。
  3. 與 C API 互操作:str.c_str() 取得 const char*,&str[0] 取得可修改緩衝區(C++11 保證連續)。
  4. 格式化輸出:fmt::format (C++20 std::format) 替代 sprintf。

總結

字串常量比較**必須用內容比較函式**,切勿用指標比較。複製操作要根據資料類型選擇 strcpy/memcpy/memmove,並嚴守緩衝區邊界。現代 C++ 開發應以 std::string/string_view 為主,將裸字串操作限制在與 C 庫互操作的邊界層。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved