2014-05-12 57 views
0

我寫了下面的代碼中的字符*數組保存並打印以下內容: band1.txt band2.txt ... band3.txt 的代碼似乎是正確的,但什麼是印在控制檯上是很奇怪。如何打印常量字符數組?

代碼:

const char ** current_band = new const char * [103]; 

stringstream sstm; 
string str; 

for (i=0;i<103;i++){ 
    current_band[i] = new char[11]; 
} 

for (i=0;i<103;i++){ 

    sstm.str(""); 
    sstm << "band" << i+1 << ".txt"; 
    str = sstm.str(); 

    current_band[i] = str.c_str(); 
    cout << current_band[i] << endl; 
    cout << i << endl; 
} 

for (i=0;i<103;i++){ 
    cout << current_band[i] << endl; 
    cout << i << endl; 
} 

控制檯:

band1.txt

band2.txt

...

band103.txt

然後最後循環:

band103.txt

band102.txt

band103.txt

band102.txt

...

band102.txt

band103.txt

這怎麼可能?

編輯:其實我想要的「帶」來爲char *爲了調用想要這樣的說法

+4

你應該使用'std :: string'和'std :: vector'來代替C字符串和原始數組。 – crashmstr

+0

該代碼不應編譯。例如,您錯過了'i'的聲明。 – Shoe

+0

_what_可能性如何?你還沒有告訴我們什麼是錯的 –

回答

4

您已經使用指針已損壞的對象不確定的行爲ifstream的current_band_file(current_band)構造函數。

只是不要使用原始指針和原始數組等等。

std::string是你的朋友的字符串,std::vector是你的朋友的數組。


例子:

#include <iostream> 
#include <string> 
#include <vector> 
using namespace std; 

auto main() 
    -> int 
{ 
    vector<string> band_names; 

    for(int i = 1; i <= 103; ++i) 
    { 
     band_names.push_back("band" + to_string(i)); 
    } 

    for(string const& name : band_names) 
    { 
     cout << name << endl; 
    } 
} 
+0

我想我可以弄明白,並找到一個字符串的解決方案,但還沒有看到未定義行爲的原因!哪些對象正在被銷燬? – iiirxs

+2

@iiirxs:語句'current_band [i] = str.c_str();'存儲一個指向局部自動變量(內部緩衝區)的指針,該指針在該塊(循環體)的末尾被銷燬。 –

+0

:-)在main()上使用尾隨返回類型 - 讓我微笑。 –

0

作爲一個創可貼,你可以更換:

current_band[i] = str.c_str(); 

if (str.size() >= 11) 
    throw std::runtime_error("string too long"); 
std::strcpy(current_band[i], str.c_str()); 

但是這將是一個更好的主意來代替這整個事情:

std::vector<std::string> current_band(103); 
int i = 0; 
for (auto &s : current_band) 
{ 
    // your sstm stuff, storing to s 
} 
0

下面是一個更強大,更可讀,更可能是正確的替代方法。

#include <vector> 
#include <iostream> 
#include <string> 
#include <sstream> 

using namespace std; 


int main() 
{ 
    vector<string> bands; 
    bands.reserve(103); 
    for(size_t i = 1 ; i <= 103 ; ++i) { 
     ostringstream ss; 
     ss << "band" << i; 
     bands.emplace_back(ss.str()); 
    } 

    for (size_t index = 0 ; index < bands.size() ; ++index) { 
     cout << index << " : " << bands[index] << endl; 
    } 

    return 0; 
} 

輸出:

Compiling the source code.... 
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1 

Executing the program.... 
$demo 
0 : band1 
1 : band2 
2 : band3 
... 
100 : band101 
101 : band102 
102 : band103 
+0

oops-忘記了.txt - 毫無疑問,你可以從那裏解決它。 –

1

作爲最小的改變你現有的代碼,你可以改變:

current_band[i] = str.c_str(); 

到:

strcpy(current_band[i], str.c_str()); 

然而,從這個移開將C和C++混合到更多地道的C +中+(如干杯和hth。 - 阿爾夫的回答)將爲你更好地爲未來服務。

的東西像char[11]std::string堅持意味着你堅持:

  • 最大長度爲11的任意選擇,即使有可能是爲限制沒有很好的技術原因。
  • 處理處理適當的C++實現隱藏的內存分配的所有細節。
  • 讀取較低級別代碼風格的自然程度要少得多。