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

終端對非打印字符顯示差異的有趣例子:C++ string 與 char 數組的行為分析

     編輯:關於C語言

現象代碼

#include <iostream>
#include <string>
using namespace std;

int main() {
    char buffer[32] = {0};
    buffer[0] = 0;      // '\0' 空字符
    buffer[1] = 'E';
    buffer[2] = 'L';
    buffer[3] = 'L';
    buffer[4] = 'O';

    string s(buffer, 32);  // 從 buffer 構造 string,長度 32
    string b = "hello";
    b = s + b;             // string 拼接

    cout << "b:" << b << endl;
    cout << "s.size():" << s.size() << endl;
    cout << "s:" << s << endl;
    cout << "s.c_str():" << s.c_str() << endl;
    return 0;
}

直接運行輸出

b:ELLOhello
s.size():32
s:ELLO
s.c_str():

現象:cout << s 只顯示 "ELLO",因為 std::string 的流輸出運算符遇到內嵌 '\0' 會停止(視為 C 字符串結束)。但 s.size() 返回 32,證明 string 內部保存了全部 32 字節。拼接 b = s + b 時,string 的 operator+ 使用長度而非 c_str(),所以完整拼接了 32 字節 + "hello",但終端顯示時 '\0' 不可見,只看到 "ELLOhello"。

重定向到文件後用 vim 查看

./a.out > a.txt
vim a.txt
 1 b:^@ELLO^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@hello
 2 s.size():32
 3 s:^@ELLO^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
 4 s.c_str():

vim 以 ^@ 顯示 NULL (0x00) 字符。可見文件確實包含了所有 32 字節的 buffer 內容,包括開頭的 \0 和後續填充的 \0。

核心結論

  • std::string 是二進制安全的,可包含任意字節(包括 \0),長度由 size() 維護。
  • cout << string 和 c_str() 面向 C 風格字符串,遇 \0 截斷。
  • 終端顯示會隱藏控制字符,重定向到文件再用編輯器查看才能看到真實二進制內容。

摘自 積累淺知識的小菜一個 -- stay hungry, stay foolish

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