2014-05-12 55 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++实现隐藏的内存分配的所有细节。
  • 读取较低级别代码风格的自然程度要少得多。