2013-01-16 51 views
1

我不一定要這樣做,但我很好奇。在C/C++中是否有一種方法可以定義字符串終止符其他比空終止符?例如,是否有可能寫這個,有沒有方法來定義「替代」字符串終止符(除了空終止符, 0)

char* str = "123456|ABCDEF"; 

char* foo = str; 
char* bar = strstr(str, "|") + 1; 

// do something here to define '|' as a terminator 

std::cout << foo << std::endl; 
std::cout << bar << std::endl; 

// undo pipe-as-terminator definition 

,並得到輸出,

123456 
ABCDEF 

如果不能,那麼有沒有任何的方式來獲得指針到緩衝區,的部分,而分配/複印內存,沒有修改緩衝區,覆蓋| s到\0小號?

+2

沒有。儘管在某些情況下它可能會很好,但零/空/零/任何的概念都深深嵌入到各處的邏輯來改變。 –

+0

不會'std :: cout << bar << std :: endl;'是UB,因爲它沒有終止? –

+0

@LuchianGrigore:大聲笑...不是真的,如果你讀的標題:*除了空終止符*。 –

回答

6

你可以寫一個字符串引用包裝拿着一個指向子和大小,然後用write而不是operator<<

// Sketch 
struct StringRef { 
    const char* start; 
    std::size_t length; 
    // add code to initialize the object out of the substring 
}; 
std::ostream& operator<<(std::ostream& o, const StringRef& s) { 
    return o.write(s.start,s.length); 
} 
0

我不認爲你可以,因爲這條規則是很難在編譯器內部構建。事實上,編譯器通過使用程序集「.asciz」指令在每個聲明常量的末尾包含null-trminator。所以除非你修改gcc的源代碼,否則我認爲你不能。我不知道其他編譯器如MSVC。對於Clang,我不知道是否有辦法做到這一點,並且需要調查。作爲一種替代方法,你可以通過硬性的方式來完成,並且將你的字符串中的每一個字符串輸入爲: const char message [] = {'H','e','l','l','o','' , '!' '|' };

但是我想指出的是,如果編譯器施加這種限制,這是一個很好的理由。例如,想象一個你從用戶處獲取輸入文本的程序。如果用戶輸入'|'會怎麼樣在他的文字?選擇空字符的原因是用戶不可能輸入這個字符(因爲它不是可打印字符集的一部分,而且我也不知道任何包含'空'鍵的鍵盤至少,你應該把另一個字符當作空終止符,但是不要輸入一個容易被輸入的字符

否則,我對操作系統開發感興趣,在這裏人們喜歡重新發明輪子,我已經看到有人嘗試過使用另一種技術:使用其長度來修飾每個字符串,允許在字符串中嵌入空字符,以及提供常量strlen()操作。另外,C#/。NET字符串是長度前綴和空終止,但我真的沒有看到它的利益...

在我更精確之前,我想知道你正在使用哪個編譯器,以及編程中的'級別'(只是不告訴你一些你不會理解的事情)x)

Cheers,Abstract

+0

從歷史上看,終端擁有「@」鍵並不罕見,在這樣的終端上,control- @通常會發送一個NUL字節。儘管NUL字節被多種行緩衝邏輯忽略,但並非所有設備都忽略它們。例如,如果啓用了紙帶打孔功能,則NUL字節將使其將紙張前移一行,而不會打孔(順便說一句,DEL由一排打孔表示,並且通常也會被忽略) 。如果一個人打錯了一個磁帶,解決辦法是將磁帶備份一行,然後在其上鍵入一個DEL字符。 – supercat