atof和非null终止字符数组
using namespace std; int main(int argc, char *argv[]) { char c[] = {'0','.','5'}; //char c[] = "0.5"; float f = atof(c); cout << f*10; if(c[3] != '\0') { cout << "YES"; } }
输出: 5YES
atof也可以使用非null终止的字符数组吗? 如果是这样,它怎么知道停在哪里?
atof也可以使用非null终止的字符数组吗?
不,它没有 。 std::atof
在输入中需要以null结尾的字符串。 未能满足此前提条件的是未定义行为 。
未定义的行为意味着任何事情都可能发生,包括程序似乎工作正常。 这里发生的是偶然你在数组的最后一个元素之后的内存中有一个字节,它不能被解释为浮点数表示的一部分,这就是你的std::atof
停止的原因。 但这是不可靠的。
你应该这样修复你的程序:
char c[] = {'0', '.', '5', '\0'}; // ^^^^
不, atof
不适用于非空终止的数组:只要在传入的数组结束后发现零就会停止。传递没有终止的数组是未定义的行为,因为它导致函数读取超过结束数组。 在你的例子中,函数可能已经访问了你已经分配给f
字节(尽管那里没有确定性,因为f
不需要在内存中跟随c[]
)。
char c[] = {'0','.','5'}; char d[] = {'6','7','8'}; float f = atof(c); // << Undefined behavior!!! float g = atof(d); // << Undefined behavior!!! cout << f*10;
上面打印了 5.678
,指出了一个超过数组末尾的读取的事实。
No … atof()需要以null结尾的字符串。
如果你有一个字符串,你需要转换不是空终止,你可以尝试将它复制到目标缓冲区,基于每个字符的值是一个有效的数字。 有什么影响……
char buff[64] = { 0 }; for( int i = 0; i < sizeof( buff )-1; i++ ) { char input = input_string[i]; if( isdigit( input ) || input == '-' || input == '.' ) buff[i] = input; else break; } double result = atof( buff );
从MSDN上的atof()
函数的描述(可能适用于其他编译器):
该函数停止读取第一个字符处的输入字符串,该字符串无法识别为数字的一部分。 该字符可以是终止字符串的空字符(’\ 0’或L’\ 0’)。
它必须是0终止或文本必须包含不属于该数字的字符。
std :: string已经用NULL终止了一个字符串!
那么为什么不呢
std::string number = "7.6"; double temp = ::atof(number.c_str());
您也可以使用stringstream或boost :: lexical_cast来完成
http://www.boost.org/doc/libs/1_53_0/doc/html/boost_lexical_cast.html http://www.cplusplus.com/reference/sstream/stringstream/