如何从字符串转换为char []使其更长?

时间:2013-03-15 15:35:26

标签: c++ arrays string

我有一个问题我无法理解它是如何存在的。

我有一堆按时间排序并包含一堆对象的文件。结果应该是每个对象的目录中每次排序一个文件。

它工作得很好但是在我将Outputstring转换为char[]以使用fstream.open()时,数组的字符数比字符串多3个字符。

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
    string strOutput;
    char *OutputFile;
    short z;

    strOutput = "/home/.../2046001_2013-02-25T0959.txt";
    cout << strOutput << endl;

    OutputFile = new char[strOutput.length()];
    z = 0;
    while (z < strOutput.length())
    {
            OutputFile[z] = strOutput[z];
            z++;
    }

    cout << OutputFile << endl;

    return 0;
}

第一个输出始终是正确的,但第二个输出有时结束.txt60A.txt5.a.txt9.A。 当它发生时,它始终是相同的对象和时间,每次尝试都会发生。但并非每个对象都这样做。

由于显而易见的原因,我无法在这个最小的代码片段中重现此错误,但我也不想发布整个390行代码。

你有什么建议吗?

3 个答案:

答案 0 :(得分:4)

您缺少在C字符串末尾终止null。修复:

OutputFile = new char[strOutput.length() + 1]; // notice +1
z = 0;
while (z < strOutput.length())
{
    OutputFile[z] = strOutput[z];
    z++;
}
OutputFile[z] = 0; // add terminating 0 byte

当然有更好的方法来完成整个事情......你根本不需要复制,只需要摆脱OutputFile和整个循环,并使用{{{}内的char数组1}}:

std::string

我认为真正的代码需要一个C字符串。 cout << strOutput.c_str() << endl; 可以直接打印std::cout,当然:

std::string

如果您确实想要创建副本,最好只复制cout << strOutput << endl; 并存储它,并在需要时使用c_str-method获取C缓冲区:

std::string

如果你知道你真的需要从堆分配的原始字符数组,你应该使用string OutputFile = strOutput; (或者可能是其他一些C ++智能指针类)来包装指针,所以你不需要手动删除并避免内存泄漏,也可以使用标准库函数进行复制:

std::unique_ptr

...

#include <memory>
#include <cstring>

答案 1 :(得分:1)

Char数组需要额外的空字符或\0附加到结尾,否则读取字符串的代码将运行到数组的末尾,直到找到它为止。

OutputFile = new char[strOutput.length() + 1];
z = 0;
while (z < strOutput.length())
{
    OutputFile[z] = strOutput[z];
    z++;
}
OutputFile[z] = '\0';

如果数组后面的下一个字节恰好为空,它似乎可以工作,但这只是巧合。我确信这就是你的代码在第一次通过时的原因。

答案 2 :(得分:0)

  
    

我将Outputstring转换为char []以使用fstream.open()

  

你不必这样做。做这样的事情:

outfile.open(Outputstring.c_str(), std::fstream::out)

当然,如果你有一个符合C ++ 11的编译器,你可以这样做:

outfile.open(Outputstring, std::fstream::out)