2013-03-15 20 views
0

我有一個問題,我真的不明白它可能存在。如何從字符串轉換爲char []使其更長?

我有一大堆的按時間排序,幷包含了一堆對象的文件。結果應該是每個對象每次在目錄中排序一個文件。

它工作的很好,但在將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行代碼。

你有什麼建議嗎?

+7

['strOutput.c_str()'](HTTP ://en.cppreference.com/w/cpp/string/basic_string/c_str) – 2013-03-15 15:36:05

+8

你不復制nul終止符。 – Pubby 2013-03-15 15:36:17

回答

4

你缺少在C字符串的結尾終止空。要解決:

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數組std::string

cout << strOutput.c_str() << endl; 

我假設真正的代碼需要一個C字符串。 std::cout可以直接打印std::string,當然:

cout << strOutput << endl; 

如果你真的想創建一個副本,最好把剛纔複製std::string和商店,並使用c_str法,你什麼時候能得到C緩衝區需要:

string OutputFile = strOutput; 

如果你知道你真正需要從堆,Y分配的原始字符數組OU應該使用std::unique_ptr(或可能還有一些其他的C++智能指針類)來包裝指針,所以你不需要手動刪除,避免內存泄漏,並且還使用標準庫函數來完成複製:

#include <memory> 
#include <cstring> 

。 ..

unique_ptr<char[]> OutputFile(new char[strOutput.length() + 1]; 
::strcpy(OutputFile, strOutput.c_str()); // :: means top level namespace 
+0

'fs_output.open(strOutput.c_str(),ios :: out | ios :: binary);'不起作用。 它說有一個無效的指針。 但循環工作正常。謝謝! – FThewes 2013-03-15 16:01:26

+0

@FThewes奇怪...還記得''刪除[]'字符數組......也可以使用智能指針,因爲在大多數「真正的」應用程序中,C++代碼應該永遠不需要調用delete當被一些較舊的圖書館API或其他非常罕見的東西授權時)。 – hyde 2013-03-15 16:10:13

1

字符陣列需要一個額外的空字符或\0追加到末尾,否則代碼讀取字符串將運行經過所述陣列的端部,直到找到一個。

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

如果數組後面的下一個字節恰好爲空,但這只是一個巧合而已。我相信這就是爲什麼你的代碼在第一遍上運行。

0

在那裏我轉換Outputstring爲char []使用fstream.open(點)

你不必這樣做。做這樣的事情,而不是:

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

當然,如果你有一個標準的11-C++編譯器,你可以做:

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

我試圖做到這一點,但我得到了一個 *** *** glibc檢測到*** ./test:munmap_chunk():無效指針:0x00007fbc9bc928d2 *** ' – FThewes 2013-03-15 16:18:42