字符串到字符转换错误?

时间:2013-12-08 03:04:02

标签: c++

尝试约1小时后,我的代码因此无法正常工作:

void s_s(string const& s, char data[10])
{
    for (int i = 0; i < 10; i++)
        data[i] = s[i];
}

int main()
{
    string ss = "1234567890";
    char data[10];
    s_s("1234567890", data);

    cout << data << endl;//why junk
}

我根本不明白为什么cout在char数组后显示垃圾。有人可以解释为什么以及如何解决它?

4 个答案:

答案 0 :(得分:6)

你需要null终止你的char数组 std::cout.operator<<(char*)使用\0知道停止的位置 顺便说一下,char[]衰减到char*

here

答案 1 :(得分:2)

如前所述,您希望NUL终止您的阵列,但这里还有其他需要考虑的事项:

如果s是您的源字符串,那么您希望循环到s.size(),这样就不会循环超过源字符串的大小。

void s_s(std::string const& s, char data[20])
{
    for (unsigned int i = 0; i < s.size(); i++)
        data[i] = s[i];
    data[s.size()] = '\0';
}

或者,你可以试试这个:

std::copy(ss.begin(), ss.begin()+ss.size(),
  data);
data[ss.size()] = '\0';

std::cout << data << std::endl;

答案 2 :(得分:2)

您只为数据分配了10个字节

该字符串实际上是11个字节,因为最后有一个隐含的'\0'

至少应该将数据大小增加到11,并更改循环以复制'\0'

答案 3 :(得分:0)

您尝试在main的最后一行使用的函数std::ostream::operator<<会将char数组作为指针,并将每char打印一次,直到 null找到了sentinel 字符(字符为\0)。

此定标字符通常在定义了C字符串文字的语句中为您生成:

char s[] = "123";

在上面的示例中,sizeof(s)4,因为存储的实际字符是:

'1', '2', '3', '\0'

最后一个字符是需要在const char*字符串的每个字符串上循环的任务的基础,因为循环终止的条件是必须读取\0

在您的示例中,您看到的“垃圾”是内存中0个字节后面的字节(解释为char)。此行为显然未定义,可能导致程序崩溃。

一个解决方案是显然在char数组的末尾添加\0 char(当然固定大小)。

但是,最好的解决方案是永远不要将const char*用于字符串。您在示例中正确使用了std::string,这可以防止出现此类问题以及其他许多问题。

如果您需要const char*(例如,对于C API),您始终可以使用std::string::c_str并检索std::string的C字符串版本。

您的示例可以重写为:

int main(int, char*[]) {
    std::string ss = "1234567890";
    const char* data = ss.c_str();
    std::cout << data << std::endl;
}

(在此特定情况下,std::ostream::operator<<的{​​{1}}版本已定义std::string,因此您甚至根本不需要data

相关问题