问题
The following code works fine when reading two .txt files containing two 5X5 array.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
string myFile, mysecondFile, mystring;
string DIR;
string extension;
int total = 0;
int number_of_lines = 0;
string line;
extension = ".txt";
DIR = "H:\\Year2\\EE273\\EE273\\Week6\\";
cout << "Enter the name of the file: \t";
cin >> myFile;
cout << "Enter the name of the second file: \t";
cin >> mysecondFile;
myFile = DIR + myFile + extension;
mysecondFile = DIR + mysecondFile + extension;
ifstream inFile;
ifstream inFile2;
int i=5;
int j=5;
int i2=5;
int j2=5;
int i3=5;
int j3=5;
int k;
int l;
int Array[5][5];
int Array2[5][5];
int Array3[5][5];
string attempt1,attempt2;
int row = 0;
int col = 0;
int row2 = 0;
int col2 = 0;//i = row
//y = column
inFile.open(myFile.c_str());
if (!inFile) {
cout <<"Error opening file"<<myFile<<endl;
return -1;
}
while (!inFile.eof())
{
getline(inFile, attempt1);
stringstream iss( attempt1 );
string result;
col = 0;
while (getline( iss, result, ','))
{
//cout << result << endl;
Array[row][col] = atoi(result.c_str());
//j = j + 1;
col = col + 1;
}
row = row + 1;
}
inFile.close();
inFile2.open(mysecondFile.c_str());
if (!inFile2) {
cout <<"Error opening file"<<mysecondFile<<endl;
return -1;
}
while (!inFile2.eof())
{
getline(inFile2, attempt2);
stringstream iss( attempt2 );
string result2;
col2 = 0;
while (getline( iss, result2, ','))
{
//cout << result2 << endl;
Array2[row2][col2] = atoi(result2.c_str());
col2 = col2 + 1;
}
row2 = row2 + 1;
}
inFile2.close();
/*for (int i=0;i<5;i++){
for (int j=0; j<5; j++){
cout<<Array[i][j]<<endl;}}
for (int i2=0;i2<5;i2++){
for (int j2=0; j2<5; j2++){
cout<<Array2[i2][j2]<<endl;
}}
Here I am carrying out the multiplication between the two matrices and writing the resulting values to a third matrix.
int Total=0;
i=0;
j2=0;
j=0;
j3=0;
for (i3=0; i3<5; i3++) {
while(j3<5){
while (j<5){
for (i2=0;i2<5;i2++){
Total += Array[i][j]*Array2[i2][j2];
j++;
Array3[i3][j3]=Total;
}}
j=0;
j2++;
j3++;
Total=0;
}
i++;
j=0;
j2=0;
j3=0;
Total=0;
}
My question is: what is the easiest way to modify the code so that it can read two .txt files containing an array of any size and then carry out the multiplication successfully?
EDIT I have to do this using arrays only, I can't use vectors unfortunately.
Am I correct in thinking the new operator is involved?
回答1:
The "easiest" way would be to do something naive, like reading the file once fully to get the number of rows/cols, then reading the file again to actually store the values in the matrix:
unsigned int rows = 0;
unsigned int cols = 0;
std::string line;
while (std::getline(inFile, line)) {
rows++;
std::stringstream ss(line);
std::string col;
while (std::getline(ss, col, ',')) {
cols++;
}
}
// Now allocate the rows*cols matrix
int** matrix = new int*[rows];
for (int i = 0; i < rows; i++) {
matrix[i] = new int[cols];
}
// and read your values into the matrix ...
// matrix[m][n] = xxx
It's pretty inefficient to read a file twice; and there are other ways to obtain the size beforehand. For example you could have a convention in your input file to include the matrix width/height before the data:
[infile.txt]
3,3
1,2,3
4,5,6
7,8,9
Now you can read the first line of the file, and you'll know that the rest of this file contains a 3x3 matrix. Allocate your matrix with new (similar to above example), then continue to read the rest of the file into it.
Remember to clean up your dynamically allocated matrices with delete[]. There should be 1 call to delete for every call to new.
for (int i = 0; i < rows; i++) {
delete[] matrix[i];
}
delete[] matrix;
回答2:
Use std::vector instead of raw arrays. E.g. you can push_back an item on a vector. And more crucially, you can create it with a size known only at run-time, e.g. from information in a file.
回答3:
The easiest approach requires the file to contain the size of the matrix as its first entries. With that, you can fallback to using C (C++ does not tolerate matrices of dynamic size) and do the following:
Read the dimension of the matrix into variables
widthandheigh.Allocate the matrix using
int (*dynamicMatrix)[width] = malloc(height*sizeof(*dynamicMatrix));Reuse your code to fill the matrix.
If you can't fall back to C, and can't use std::vector<>, the only thing left to you is to use a double pointer:
int**dynamicMatrix = new int*[height];
for(size_t i = width; i--; ) dynamicMatrix[i] = new int[width];
Again, this is easiest if you can define the first two numbers in a file to contain the width and height of the matrix in the file. If you can't code these two numbers into your file, you have to grow your dynamic arrays as you go:
size_t lines = 0, allocatedLines = 8;
int** dynamicMatrix = new int*[allocatedLines];
while(/* can read a line */) {
if(lines == allocatedLines) {
int** temp = new int*[allocatedLines *= 2];
for(size_t i = lines; i--; ) temp[i] = dynamicMatrix[i];
delete[] dynamicMatrix;
dynamicMatrix = temp;
}
//add one line
size_t curLineLength = 0, allocatedLineLength = 8;
dynamicMatrix[lines++] = new int[allocatedLineLength];
//fill the line
...
}
A similar block for reallocating a line would need to go into the loop where you read the elements of a single line. This is tedious; but the only way to get better is to use stuff that you are not allowed to use.
Btw: even the reallocating stuff is easier in C, since it provides the realloc() function:
size_t lines = 0, allocatedLines = 8;
int** dynamicMatrix = malloc(allocatedLines * sizeof(*dynamicMatrix));
while(/* can read a line */) {
if(lines == allocatedLines) {
//realloc takes care of copying the data to a new location (if that is necessary):
allocatedLines *= 2;
dynamicMatrix = realloc(dynamicMatrix, allocatedLines * sizeof(*dynamicMatrix));
}
//add one line
size_t curLineLength = 0, allocatedLineLength = 8;
dynamicMatrix[lines++] = malloc(allocatedLineLength * sizeof(**dynamicMatrix));
//fill the line
...
}
Since there is no equivalent to realloc() to work with new/delete, you are required to either use std::vector<> in C++, or to do the copying yourself as above.
来源:https://stackoverflow.com/questions/27485504/reading-arbitrary-array-of-any-size