【发布时间】:2016-06-13 07:18:36
【问题描述】:
据我了解,C 风格的字符串,即使在 C++ 中使用而不是字符串类,也需要一个空终止字符:
This is a string.\0
据我了解,缺少空字符会导致程序继续读取内存中字符串之后的任何内容,直到找到空字符的二进制表示。这显然是未定义的行为。
在编写 dtoi 函数时(我想自己编写这个函数作为我正在做的不同实践项目的一部分进行实践——我知道已经有图书馆设施可以做到这一点),我发现了不同的行为(特别是在创建invalid_argument 异常的字符串)。
int dtoi(const char d){
switch(d){ //using switch statement rather than d-'0' to support character sets with non-consecutive digits or digits that go from 9 to 0 rather than 0 to 9
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
default:
throw invalid_argument(((d == '\0') ? "null character" : &d) + string(" is not a valid digit character."));
}
}
由于异常字符串开头的空字符导致它在第一个字符处结束(即,当空字符被传递给我的 dtoi 实现时),我决定让它显示文本“空字符”如果它是'\0',而不是直接插入字符。为了实现这一点,我使用了条件运算符。我不能使用(d == '\0') ? "null character" : d(注意它在结尾处是d而不是&d),因为条件运算符可能会返回指向字符串文字中第一个字符的指针或直接返回一个字符。为了看看发生了什么,我决定尝试&d,令我惊讶的是,它打印了在 exception.what() 中传递给函数的任何字符。我希望它提供一个指向传递字符的指针,但是,然后继续读入随机内存,直到找到一个空字符。我尝试了多次,并传入了多个不同的字符。为什么它的行为是这样的?我真的认为它是未定义的行为是正确的,它恰好在这里按预期工作吗?
【问题讨论】:
-
因为未定义的行为。
-
致任何投反对票的人:我不确定您为什么要这样做——这似乎是一个有效的问题。我在问一个特定的动作是否实际上是未定义的行为,或者我是否误解了 C++ 的工作原理。如果这在某种程度上无效,请告诉我而不是投反对票。
-
@juanchopanza 这听起来很像一个答案。
-
"不连续数字的字符集或从 9 到 0 而不是从 0 到 9 的数字" 没有这样的东西。
-
好吧,这并不可怕,但它过于冗长。您可以将 20 行替换为 2:
if ( d >= '0' && d <= '9' ) return d - '0';(带换行符)。我想大多数人更愿意阅读后者
标签: c++ c arrays string pointers