I have written the following code to save in an char * array and print the following content: band1.txt band2.txt ... band3.txt The code seems right but what is printed on the console is very weird.
Code:
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;
}
Console:
band1.txt
0
band2.txt
1
...
band103.txt
102
And then for the last loop:
band103.txt
0
band102.txt
1
band103.txt
2
band102.txt
3
...
band102.txt
101
band103.txt
102
How is this even possible?
EDIT: Actually i want the "bands" to be char* in order to call the ifstream current_band_file(current_band) constructor that wants such an argument
You have undefined behavior by using pointers to already destroyed objects.
Simply don't use raw pointers and raw arrays and such stuff yet.
std::string
is your friend for strings, std::vector
is your friend for arrays.
Example:
#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;
}
}
As a minimal change to you existing code you can change:
current_band[i] = str.c_str();
to:
strcpy(current_band[i], str.c_str());
However, moving away from this mixed C and C++ to more idiomatic C++ (like Cheers and hth. - Alf's answer) will serve you better for the future.
Sticking with things like char[11]
over std::string
means you're stuck with:
As a band-aid you could replace:
current_band[i] = str.c_str();
with
if ( str.size() >= 11 )
throw std::runtime_error("string too long");
std::strcpy(current_band[i], str.c_str());
However it would be a much better idea to replace this whole thing with:
std::vector<std::string> current_band(103);
int i = 0;
for (auto &s : current_band)
{
// your sstm stuff, storing to s
}
Here's an alternative way that's a little more robust, readable and more likely to be correct.
#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;
}
output:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.