I want to write something like 2d strings in C++. I tried with :
vector< vector<string> > table;
int m,n,i,j;
string s;
cin>>n>>m;
for(i=0;i<n;i++) {
for(j=0;j<m;j++) {
cin&g开发者_如何转开发t;>s;
table[i][j] = s;
}
}
cout << "\n\n\n\n";
for(i=0;i<n;i++) {
for(j=0;j<m;j++) {
cout<<table[i][j]<<" ";
}
cout<<"\n";
}
no compile errors, but when i enter input like:
10 20
.....#..............
.....#..............
.....#..............
.....#..............
######..............
.......###..........
.......#.#..........
.......###...#######
.............#.....#
.............#######
It gives me segmentation fault. Why ? What's wrong ? And how it should be done so it would work correctly ? Thank you.
The question seems to imply that the data structure needed is a set of n
lines with m
characters each. There are two ways to think of this -- as an nxm
char matrix, or as n
m
-character vectors (and a string is similar but not identical to vector<char>
).
So it seems you don't want a vector
of vector
s of string
s, you want either a vector
of vector
s of char
s, or just a vector
of string
s.
In any event, you have to allocate the appropriate amount of space before using table[i][j] or (slightly more idiomatic c++, but not necessary in this case since m
and n
are known beforehand) use something like push_back
to add to the end.
Note also that the cin>>s
reads an entire line from stdin
(which makes the vector<string>
solution a bit easier to deal with, I think).
When inserting something new into a vector
, you can't just allocate by index - you need to use the push_back
method or something similar.
for(i=0;i<n;i++) {
vector<string> row;
for(j=0;j<m;j++) {
cin>>s;
row.push_back(s);
}
table.push_back(row);
}
The vector
class has a ctor that takes the size and an element, so:
vector< vector<char> > table(ROW_COUNT, vector<char>(COLUMN_COUNT, '.'));
would initialize a vector containing ROW_COUNT
copies of the vector passed as the second argument, which contains COLUMN_COUNT
times .
.
It is an error to index a vector that you haven't inserted into yet.
So taking a more easy example:
std::vector<int> v;
v[0] = 3;//bad, v[0] doesn't exist yet
Correct:
std::vector<int> v;
v.push_back(3);
int x = v[0];//ok
But in your case you are first inserting into a vector and then pushing the whole vector into the other vector.
I think a vector<vector<char> >
would be better suitable for your purposes.
You vector
s are still empty and you probably wan't to . You can either append values using e.g. push_back()
or init them with a suitable size:
std::cin >> n >> m;
typedef std::vector<std::string> StringVec;
std::vector<StringVec> table(n, StringVec(m));
As others mentioned though, std::string
might not be what you really need.
You need to use char s; cin.get(s);
instead of string s; cin>>s;
, becuase cin>>s
will read a whole word (in your sample this is equivalent to a whole line) at a time.
Additionally, you need to do something to get the size of each array right. In your code you have a vector of 0 vectors of 0 strings. For example:
vector< vector<string> > table;
int m,n,i,j;
char s;
cin>>n>>m;
for(i=0;i<n;i++) {
table.push_back(vector<string>());
for(j=0;j<m;j++) {
cin.get(s);
table[i].push_back(string(1,s));
}
}
cout << "\n\n\n\n";
for(i=0;i<n;i++) {
for(j=0;j<m;j++) {
cout<<table[i][j]<<" ";
}
cout<<"\n";
}
You must create vector of elements, to add elements you must use v.insert(v.end(), s)
. and finnaly (when you have full row data). you must write tables.insert(tables.end(), v)
精彩评论