Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有没有一种方法来定义“的含义?”;候补;字符串终止符(除空终止符之外,\0)_C++_C_String_Performance_Null Terminated - Fatal编程技术网

C++ 有没有一种方法来定义“的含义?”;候补;字符串终止符(除空终止符之外,\0)

C++ 有没有一种方法来定义“的含义?”;候补;字符串终止符(除空终止符之外,\0),c++,c,string,performance,null-terminated,C++,C,String,Performance,Null Terminated,我不一定想这么做,但我很好奇。在C/C++中,有没有一种方法可以定义除空终止符以外的字符串终止符?比如说,有没有可能写下这个 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

我不一定想这么做,但我很好奇。在C/C++中,有没有一种方法可以定义除空终止符以外的字符串终止符?比如说,有没有可能写下这个

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
?


如果不可能,那么是否有任何方法可以获取指向缓冲区部分的指针,而无需分配/复制内存,也无需修改缓冲区,即将
s覆盖到
\0
s?

您可以编写一个字符串引用包装器,其中包含指向子字符串和大小的指针,然后使用
write
而不是
operator您可以编写一个包含指向子字符串和大小的指针的字符串引用包装器,然后使用
write
而不是
operator我不认为您可以,因为这条规则在编译器内部很难构建。事实上,编译器通过使用assembly“.asciz”指令在您声明的每个字符串常量的末尾包含null trminator。因此,除非您修改gcc的源代码,否则我认为您不能。我真的不知道其他编译器,比如MSVC。对于Clang,我不知道是否有办法这样做,这需要调查。另一种选择是,你可以用一种很难的方式把你的每一个字符串都打成
const char message[]={'H','e','l','l','o','','!','|'}

但我想指出,如果编译器施加这种限制,这是有充分理由的。例如,想象一个程序,从用户那里获取输入文本。如果用户在文本中输入“|”怎么办?选择空字符的原因是用户无法输入此字符(因为它不是可打印字符集的一部分,而且我不知道任何键盘是否包含“null”键。至少,您应该使用另一个字符作为null终止符,但不要使用易于输入的字符

除此之外,我对操作系统开发感兴趣,人们喜欢重新发明轮子,我已经看到有人尝试使用另一种技术:用长度固定每个字符串,允许在字符串中嵌入空字符,以及提供恒定时间strlen()此外,C#/.NET字符串是以长度为前缀并以null结尾的,尽管我并不认为它有什么意思

在更精确地介绍之前,我想知道您使用的是哪种编译器,以及您在编程方面的“水平”(只是不想告诉您您不理解的事情)


干杯,Abstract

我不认为您可以,因为这条规则在编译器内部是很难建立的。事实上,编译器在您声明的每个字符串常量的末尾包含null trminator,方法是使用assembly.asciz指令。因此,除非您修改gcc的源代码,否则我认为您不能。其他方面我真的不知道像MSVC这样的编译器。对于Clang,我不知道是否有这样做的方法,这需要调查。作为一种替代方法,你可以用很难的方法来做,并将你的每个字符串输入为 const char message[]={'H','e','l','l','o','','!','|'}

但我想指出,如果编译器施加这种限制,这是有充分理由的。例如,想象一个程序,您从用户那里获取输入文本。如果用户在其文本中输入“|”,该怎么办?选择空字符的原因是用户不可能输入此字符(因为它不是可打印字符集的一部分,而且我不知道任何键盘是否包含“null”键。至少,您应该使用另一个字符作为null终止符,但不要使用易于输入的字符

除此之外,我对操作系统开发感兴趣,人们喜欢重新发明轮子,我已经看到有人尝试使用另一种技术:用长度固定每个字符串,允许在字符串中嵌入空字符,以及提供恒定时间strlen()此外,C#/.NET字符串是以长度为前缀并以null结尾的,尽管我并不认为它有什么意思

在更精确地介绍之前,我想知道您使用的是哪种编译器,以及您在编程方面的“水平”(只是不想告诉您您不理解的事情)


干杯,Abstract

不。虽然在某些情况下它可能很好,但零/空/零/任何东西的概念在逻辑中都根深蒂固,无法改变。如果你读了标题:除了空终止符之外。@DavidRodríguez dribeas不,我没有。不,尽管在有些情况下,零/零/零/零/任何东西的概念都深深地嵌入到逻辑中,无法改变。如果你读了标题:除了零终止符之外,
std::cout@LuchianGrigore:lol…就不会了。@DavidRodríguez dribeas不,我没有。从历史上看,终端有
@
键的情况并不少见;在这个术语上inals,control-@通常会发送一个NUL字节。虽然NUL字节被许多类型的行缓冲逻辑忽略,但并非所有设备都会忽略它们。例如,如果启用纸带打孔,NUL字节将使纸张向前移动一行,而不打孔(顺便说一句,DEL由一行表示,其中所有孔都已打孔,通常也会被忽略)。如果打孔磁带出错,解决方法是将磁带备份一行,然后在其上键入DEL字符。历史上,终端有
@
键的情况并不少见;在此类终端上,control-@通常会发送NUL字节。虽然NUL字节被许多类型的行缓冲逻辑忽略,但并非所有设备都有nt忽略它们。例如,如果启用纸带打孔,NUL字节将使纸带向前移动一行,而不使用pun
123456
ABCDEF
// 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);
}