我被困在一个简单的代码段中:
#include <iostream>
#include <stdio.h>
#include<cstring>
#include <algorithm>
int main()
{
int l;
std::cin >> l;
char leading[l];
//std::fill_n(leading, l, '0');
memset(leading, '0', sizeof(char)*l);
std::cout << "->" << leading << "<- strlen=" << strlen(leading) << std::endl;
}
以下是多次运行的结果(与std::fill_n
相同的问题):
~/test$ g++ ptr.cpp
~/test$ ./a.out
3
->000*�<- strlen=6
~/test$ ./a.out
7
->0000000<- strlen=7
~/test$ ./a.out
6
->000000<- strlen=6
~/test$ ./a.out
5
->00000<- strlen=6
~/test$ ./a.out
2
->00@��<- strlen=6
我是否需要寻找其他工作?
更新
正如我稍后将在sprintf
中使用此数组,我不想使用null终止符。还有更好的选择吗?
答案 0 :(得分:2)
'0'
不与'\0'
相同,这可能是您想要的。 (C ++支持的 encoding 系统不允许将字符文字'0'
设置为值0。)
在此内存块上使用strlen
的行为将是未定义的。
如果要填充字符0,请记住在内存块中添加NUL终结符,以便可以使用C类型字符串函数(以及<<
)。
答案 1 :(得分:2)
strlen
和operator<<(basic_ostream&, char*)
都有前提条件,指针参数指向以空字符结尾的字符串。您的数组不会以空值终止,因此您违反了这些前提条件。因此,程序的行为未定义。
更新:我不使用null终止符。还有更好的选择吗?
由于您已经知道长度strlen
,因此无需替代l
。
对于非空终止字符数组的流式传输,您可以使用迭代器:
std::ostream_iterator<char> it(std::cout);
std::copy(leading, std::end(leading), it);
PS。
std::cin >> l; char leading[l];
这在C ++中是不正确的。数组的大小必须是编译时常量。
答案 2 :(得分:1)
因为strlen和cout都依赖于null终止符来指示字符串的结尾