问题
What is the simplest way to read/input a matrix of numbers into an array in C++?
This is the file content (dimensions are unknown):
283 278 284 290 290 286 273 266 266 266 261 252 246
382 380 379 381 382 379 384 387 385 382 376 365 357
285 282 281 279 276 273 272 264 255 255 247 243 237
196 190 186 183 183 180 179 186 191 195 195 188 187
245 237 226 220 221 222 225 228 234 245 252 264 272
283 278 284 290 290 286 273 266 266 266 261 252 246
I've tried a lot of suggested codes, but non of them seem to work for me... :( I want to do the following with the matrix:
MATRIX[i][j] = MATRIX[i][j] + rand()-RAND_MAX/2;
What to include in the if loop to read the matrix??
#include <iostream>
#include <fstream>
ifstream pFile;
pFile.open("test.txt");
if (pFile.is_open())
{
// SOMETHING HERE!!!!!??
}
else
{
printf("Error reading the file!\n");
return 1;
}
回答1:
First, as others suggested, use a std::vector<std::vector<int>>
. It will make things a lot simpler.
#include <vector>
typedef std::vector<int> IntVector;
typedef std::vector<IntVector> IntVector2D;
So our type is IntVector2D
. (I defined the one-dimensional vector to be used later)
Next, we want to set up a loop that reads one line at a time, parses the line, and stores the int's found on the line in one row of the matrix. To do that, we can read the line into a string, and use istringstream
to do the parsing.
Last, for each line stored, we apply the changes to each item on the row according to your random number function.
So here is a sample of all of this put together:
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iostream>
typedef std::vector<int> IntVector;
typedef std::vector<IntVector> IntVector2D;
using namespace std;
// random number function to apply
int ApplyRand(int num)
{ return num + rand() - RAND_MAX/2; }
void OutputMatrix(const IntVector2D& m)
{
cout << "\n";
IntVector2D::const_iterator it = m.begin();
while (it != m.end())
{
copy(it->begin(), it->end(), ostream_iterator<int>(cout, " "));
cout << "\n";
++it;
}
}
// Transform the numbers in the matrix
void TransformMatrix(IntVector2D& m)
{
IntVector2D::iterator it = m.begin();
while (it != m.end())
{
transform(it->begin(), it->end(), it->begin(), ApplyRand);
++it;
}
}
int main()
{
IntVector2D matrix;
ifstream pFile("test.txt");
string s;
while ( std::getline(pFile, s) )
{
// create empty row on back of matrix
matrix.push_back(IntVector());
IntVector& vBack = matrix.back();
// create an istringstream to parse
istringstream ss(s);
// parse the data, adding each number to the last row of the matrix
copy(istream_iterator<int>(ss), istream_iterator<int>(), back_inserter(vBack));
}
// output the matrix
OutputMatrix(matrix);
// Apply rand to each number
TransformMatrix(matrix);
// output the updated matrix
OutputMatrix(matrix);
}
Output:
283 278 284 290 290 286 273 266 266 266 261 252 246
382 380 379 381 382 379 384 387 385 382 376 365 357
285 282 281 279 276 273 272 264 255 255 247 243 237
196 190 186 183 183 180 179 186 191 195 195 188 187
245 237 226 220 221 222 225 228 234 245 252 264 272
283 278 284 290 290 286 273 266 266 266 261 252 246
-16059 2362 -9765 10407 3076 -373 -4632 13241 10845 8347 -10417 12014 7144826
-6042 -15513 -13007 -4059 -11177 -10563 16395 -1394 -12099 -15854 -15726 -3644
1323 2615 3616 3791 -10660 5616 -1340 -4581 -14259 3784 9531 10159 889
-6293 12510 7614 15122 14133 1470 -11540 -1056 -8481 12065 -9320 9352 11448
16524 16611 3880 -3304 -7439 -6420 11371 -15377 -3833 -13103 6059 -14277 -15823
14006 -7065 -7157 3171 6555 11349 7695 -227 -9388 8253 -772 -1125 14964
Note the use of std::copy
to extract the items from the istringstream
, and back_inserter
, which is responsible for calling push_back
on the last row of the matrix.
Also, the usage of std::transform
allows us to call a function on each element, "transforming" the element from the original value to the changed value using ApplyRand
as the function to do this transformation.
回答2:
Here's a simple way to read in a matrix of unknown size using vectors. The advantage of vectors over arrays if you don't know the dimensions that you're working with is that you don't need to worry about resizing your data structure if you run out of space.
std::vector<std::vector<int> > matrix;
std::string line;
int value;
// read in matrix
std::ifstream file("path/to/file.txt");
while(std::getline(file, line)) {
std::vector<int> row;
std::istringstream iss(line);
while(iss >> value){
row.push_back(value);
}
matrix.push_back(row);
}
回答3:
First of all, we declare a vector of vectors to keep our matrix in. Note that the advantage of vectors over arrays if you don't know the dimensions that you're working with is that you don't need to worry about resizing your data structure if you run out of space. This is why we use vectors instead of arrays. After that, we use stringstream to read all integers from input. In a while loop, we continue until there still exits another line (getline() returns true if there is no more lines). In each step, we read a line from input (no matter how long it is, we read it completely) then we seprate the line's integers and put them in a vector using string stream. Then, we add that vector to our matrxi 2D vector. I wrote this code:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <fstream>
using namespace std;
int main () {
fstream cin;
cin.open("input.txt");
string s;
vector <vector <int> > matrix;
while (getline(cin, s)) {
stringstream input(s);
int temp;
vector <int> currentLine;
while (input >> temp)
currentLine.push_back(temp);
matrix.push_back(currentLine);
}
for (unsigned int i = 0; i < matrix.size(); i++) {
for (unsigned int j = 0; j < matrix[i].size(); j++)
cout << matrix[i][j] << " ";
cout << endl;
}
return 0;
}
And the output is exactly what you want. Note that the first line can't be seen and I had to scroll up to see that but be sure it's there. Give it a try. Here's the output:
来源:https://stackoverflow.com/questions/25514273/read-matrix-to-2d-array-in-c-c