How to read in a matrix from a file in C++? - c++

I am attempting to read in an n × n matrix from a file and then store that matrix in a one dimensional array. I would also like to store the value for n. I have looked into various approaches but can't seem to apply them to what I'm trying to achieve.
This is what I have so far but I'm unsure what to put into the while loop.
/*READ IN THE IMAGE MATRIX FROM THE FILE*/
String lineA;
ifstream imFile;
imFile.open("imageMatrixDefined.txt");
if(imFile.fail()){
cerr << "File cannot be found or opened" << endl;
exit(1);
}
if(imFile.is_open(){
cout << "file opened successfully!" << endl;
while(!imFile.eof()){
}
}
The input file could look like the following:
1 2 3
2 3 1
3 3 2
where a tab separates the elements.
Any suggestions would be greatly appreciated as I'm new to C++.

Arrays have a fixed size.
You have to get the value for n first before initializing an array.
It's good to double check if you would like to store that matrix in a one dimensional array or a two dimensional array. If it is a one dimensional array, checking how the matrix is stored in a one dimensional array is good. Some stores it first row, second row, ..., and nth row, and some stores it first column, second column, ..., and nth column.
The matrix is n × n, so the number of columns is equal to the number of rows.
The file stores one row at a time.
Getting the value of n is not difficult.
The while loop is critical, but before the while loop, getting the value of n is the first step of solving the problem.
When the value of n is gotten, the array is easy to be initialized.
You can read the line one by one from the file in the while loop, get each matrix element by using the delimiter as a tab character, and store the matrix element in the array.

Reading a 2D array to a file. Input is assumed to be comma separated, one row per line and x amount of columns per row, each column separated by a tab (\t) character. No EOL (end of line) tab's required, just a newline (\n). Remember to set rows and columns variables correctly. Code is tested to work correctly.
using namespace std;
#include <iostream>
#include <fstream>
int main() {
int rows=10, columns=10;
ifstream f("input.txt");
int input[rows][columns];
for (int i=0; i<rows; i++){
for (int j=0; j<columns; j++){
f >> input[i][j];
}
}
f.close();
// Here you can add processing of the file, for example, print it:
cout << "Input:" << endl;
for (int i=0; i<rows; i++){
for (int j=0; j<columns; j++){
cout << input[i][j] << " ";
}
cout << endl;
}
return 0;
}

You have to bind a custom input stream with your input file. Say your input file is "in.txt", and it looks the same as you have specified.
The following code then reads from the file, stores it in a 1D array and prints the resulting matrix in matrix form:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ifstream myfile;
myfile.open ("in.txt");
cout << "Reading from a file.\n";
int arr[10];
int k = 0;
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
myfile >> arr[k]; //Read it in a 1D array
cout << arr[k] << " ";
++k;
}
cout << "\n";
}
myfile.close();
return 0;
}
Output:
Reading from a file.
1 2 3
2 3 1
3 3 2

Related

Cannot find solution to my program not executing properly [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
New to programming, I have tried just about everything to get my program to run, but cannot figure it out. This is for my Into to programming course, so I'll be posting the instructions for it as well for context purposes.
I know for a fact that my program is running properly up until the closing bracket in line 62. The primary issue that im having is right after that, where I call the function sharedLetters. For context, I have attempted multiple ways of trying to fix the function definition, so at this point its a little jumbled, but it was wrong to begin with, so there's that. As for the remainder of the code, im not entirely sure if its written correct or not, as I cant get beyond the called function.
Assignment Instructions
For this assignment, you will write a program that forms the basis of a crossword puzzle generator. In order to create a crossword puzzle you need to identify letters that are common to one or more words. This program helps you generate crossword puzzles by identifying letters that are common to several words and storing them in an intermediate data structure.
Using intermediate data structures is one way to simplify your coding. You create a data structure that organizes your input so the final output is easier to create. Your CrosswordGenerator program will open a file containing a list of words. To prepare for crossword puzzle generation your code should implement the following pseudo code:
Open a file named wordlist.txt
Determine the number of words (N) in the file.
Create an array of that size called wordArray[];
Read all the words from the file into an array called wordArray[N].
Sort the array of words by length in descending order
Start at the beginning of the array (the longest word) and examine the word
Find all other words in the array that can intersect the current word
Two words can intersect if they share a letter.
Write a function called String sharedLetters(String S1, String S2).
Implement sharedLetters(S1,S2) that will return a string containing letters shared by the two parameter strings S1 and S2.
If no letters are shared between S1 and S2 sharedLetters() should return the empty string "".
sharedLetters(S1,S2) should ignore case; capital and lower case letters are considered equal.
Create a two dimensional array of Strings wordsIntersect[N][N] where each dimension N is the size of wordArray.
Iterate over wordArray comparing distinct words. Do not compare a word to itself.
If wordArray[i] shares any letters with wordArray[j] place the result of sharedLetters(wordArray[i],wordArray[j]) into wordsIntersect[i][j].
Non-alphabetic characters should be ignored.
Upper and lower case letters should be equivalent. Your program should not treat them as distinct tokens.
The order of shared letters is not a consideration for this program.
Write the contents of the wordsIntersect array to a Comma Separated Values (CSV) text file named wordsIntersect.csv in row-major form: row,col,value. In the example below, there is an entry in wordsIntersect[12][33] which contains the string "tci". There would also be a line in wordsIntersect.csv that contains 12,33,tci -- there are no quotes around the letters and the line ends after the letter 'i'. Given that wordsIntersect[12][78] will contains "" there would be a line in the file containing: 12,78, where there is an end of line after the last comma.
N.B.
Example of what sharedLetters() output.
SharedLetters(transaction,dictum) returns "tci"
SharedLetters(Transaction,kudzu) returns ""
If "transaction" is stored in wordArray[12] and "dictum" is stored in wordArray[33] then wordsIntersect[12][33] will contain "tci".
If "kudzu" is stored in wordArray[78] then wordsIntersect[12][78] will contain "".
My actual code
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
using std::string;
//calling function that will record shared letters between words, to be called later
string sharedLetters(string S1[], string S2[]);
int main ()
{
//variables for indexes used in arrays
int i, compareIndex, count = 0;
//declaring array and its total size based on total words in file
const int N = 644;
string wordArray[N];
//declaring a 2-D array wordsIntersect, setting size of both dimensions to 'N'
string wordsIntersect[644][644];
//declaring file
ifstream file;
//opening file
file.open("wordlist.txt");
cout << "Reading data from the file." << endl;
while (count < N)
{
file >> wordArray[count];
count++;
}
//closing the file
cout << "Closing the wordlist.txt file now." << endl;
file.close();
//sort the array of strings in descending order using SelectionSort
//going through array of strings, wordArray[]
for (int i = 0; i < N; i++)
{
//creating a nested for loop to compare indexes
for (int compareIndex = i + 1; compareIndex < N; compareIndex++)
{
//compare the words at both indexes to determine which one is longer
if (wordArray[i].length() < wordArray[compareIndex].length())
{
//if true, swap the elements using selectionSort
string longerWord = wordArray[compareIndex];
//swap indexes i and compareIndex
wordArray[compareIndex] = wordArray[i];
wordArray[i] = longerWord;
}
}
}
//calling sharedLetters function
for(i = 0; i < N; i++)
{
for(compareIndex = 0; compareIndex < N; compareIndex++)
{
string sharedLetters(wordArray[i], wordArray[compareIndex]);
}
}
string word = string sharedLetters(wordArray[i], wordArray[compareIndex]);
cout << word << endl;
//compare every word in wordArray to every other word within the array, using the sharedLetters funtion
for (int i = 0; i < N; i++)
{
for (int compareIndex = i + 1; compareIndex < N; compareIndex++)
{
//saving a string result within the main function that will equal
//the return value of the called function in the previous step
wordsIntersect[i][compareIndex] = sharedLetters(wordArray[i], wordArray[compareIndex]);
}
}
for (int i = 0; i < N; i++)
{
for (int compareIndex = i + 1; compareIndex < N; compareIndex++)
{
cout << wordArray[i] << "," << wordArray[compareIndex] << " " << wordsIntersect[i][compareIndex] << endl;
}
}
return 0;
}
//setting up 2D array wordsIntersect
for (int i = 0; i < N; i++)
{
for (int compareIndex = 0; compareIndex < N; compareIndex++)
{
wordsIntersect[i][compareIndex];
}
}
//writing the data in 2-D array into file wordsIntersect.csv
cout << "Now opening the file wordsIntersect.csv." << endl;
ofstream outputFile;
outputFile.open("wordsIntersect.csv");
cout << "Inputting sorted array wordsIntersect within file, now." << endl;
outputFile << wordsIntersect[i][compareIndex];
//closing file
outputFile.close();
cout << "Data has successfully been entered into the file. The file is now closed." << endl;
return 0;
}
//function that will identify common letters between each word
string sharedLetters(string S1[], string S2[])
{
//declaring string for sharedLetters
string sharedletters = "";
//declaring a string for words with common letters
string commonLetter = "";
//nested for loop to compare letters in S1 and S2
for (int i = 0; i < S1.length(); i++)
{
for (int compareIndex = 0; compareIndex < S2.length(); compareIndex++)
{
//comparing letters in strings
if(S1[i] == S2[compareIndex])
{
//assigning the letter at index i whenever common is found
commonLetter = S1[i];
//adding the value of commonLetter to sharedletters
sharedletters = commonLetter;
break;
}
}
}
//return string of sharedletters
return sharedletters;
}

Sum of Multidimensional array in C++ from csv file

Would anyone be able to help me, I am trying to make a C++ program which reads values from csv file and prints them(there are going to be three 4 rows, 3 columns). I want to know how can I add the rows (like the sum of the first row =? the sum of second-row = ?...)
The matrix looks like this:
And my program looks like:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream sumCol;
sumCol.open("Col.csv");
string line;
int sum;
cout << "The entered matrix: " << endl;
while(sumCol.good()){
string line;
getline(sumCol, line, ',');
cout << line << " ";
}
while(sumCol.good()){
getline(sumCol, line, ',');
int i = stoi(line);
cout << endl;
cout << i;
}
while(getline(sumCol, line, ',')){
int i = stoi(line);
sum = sum + i;
getline(sumCol, line, ',');
i = stoi(line);
sum = sum + i;
getline(sumCol, line);
i = stoi(line);
sum = sum + i;
}
cout << sum << endl;
return 0;
}
Next try. Very simple answer with just basic constructs.
12 statements. But 2 for loops, nested and hardcoded magic numbers for rows and columns.
Please see the below well commented source code:
#include <iostream>
#include <fstream>
int main() {
// Open file
std::ifstream csv("col.csv");
// and check, if it could be opened
if (csv) {
// Now the file is open. We have 3 rows and 4 columns
// We will use 2 nested for loops, one for the rows and one for the columns
// So, first the rows
for (int row = 0; row < 3; ++row) {
// Every row has a sum
int sumForOneRow = 0;
// And every row has 4 columns. Go through all coulmns of the current row.
for (int col = 0; col < 4; ++col) {
// Read an integer value from the current line
int integerValue;
csv >> integerValue;
// Show it on the screen
std::cout << integerValue << ' ';
// Update the sum of the row
sumForOneRow = sumForOneRow + integerValue;
}
// Now, the inner for loop for the 4 columns is done. Show sum to user
std::cout << " --> " << sumForOneRow << '\n';
// Line activities are done now for this line. Go on with next line
}
}
else std::cerr << "\n*** Error: Could not open 'col.csv'\n";
return 0;
}
Third try.
Obviously the matrix, shown in the question, does not reflect the real data. The real data might look like that:
9, 1, 2, 4
9, 2, 8, 0
3, 3, 3, 3
Without using std::getline we can do like the below:
#include <iostream>
#include <fstream>
int main() {
// Open file
std::ifstream csv("r:\\col.csv");
// and check, if it could be opened
if (csv) {
// Now the file is open. We have 3 rows and 4 columns
// We will use 2 nested for loops, one for the rows and one for the columns
// So, first the rows
for (int row = 0; row < 3; ++row) {
// Every row has a sum
int sumForOneRow = 0;
// And every row has 4 columns. Go through all coulmns of the current row.
for (int col = 0; col < 4; ++col) {
// Read an integer value from the current line
int integerValue;
char c; // for the comma
// The last value, the value in column 3 (We start counting with 0) is not followed by a comma
// Therefore we add special treatment for the last column
if (col == 3)
csv >> integerValue; // Read just the value
else
csv >> integerValue >> c; // Read value and comma
// Show it on the screen
std::cout << integerValue << ' ';
// Update the sum of the row
sumForOneRow = sumForOneRow + integerValue;
}
// Now, the inner for loop for the 4 columns is done. Show sum to user
std::cout << " --> " << sumForOneRow << '\n';
// Line activities are done now for this line. Go on with next line
}
}
else std::cerr << "\n*** Error: Could not open 'col.csv'\n";
return 0;
}
4th try. Based on the evolution of this thread and the request of the OP to use std::getline
#include <iostream>
#include <fstream>
#include <string>
int main() {
// Open file
std::ifstream csv("r:\\col.csv");
// and check, if it could be opened
if (csv) {
// Now the file is open. We have 3 rows and 4 columns
// We will use 2 nested for loops, one for the rows and one for the columns
// So, first the rows
for (int row = 0; row < 3; ++row) {
// Every row has a sum
int sumForOneRow = 0;
// And every row has 4 columns. Go through all coulmns of the current row.
for (int col = 0; col < 4; ++col) {
// Read a substring up to the next comma or end of line
std::string line;
// Special handling for last column. This is not followed by a comma
if (col == 3)
std::getline(csv, line);
else
std::getline(csv, line, ',');
// Convert string to line
int integerValue = std::stoi(line);
// Show it on the screen
std::cout << integerValue << ' ';
// Update the sum of the row
sumForOneRow = sumForOneRow + integerValue;
}
// Now, the inner for loop for the 4 columns is done. Show sum to user
std::cout << " --> " << sumForOneRow << '\n';
// Line activities are done now for this line. Go on with next line
}
}
else std::cerr << "\n*** Error: Could not open 'col.csv'\n";
return 0;
}
IMHO this is more complicated than 3rd try
Yes, I can help you with a piece of code, but I am not sure, if you will understand the more modern C++ language elements.
So, what do we need to do?
Read line by line of the source csv string
Get all integer values for this line
The interger values are arranged in columns and separated by white space
Show the values and the screen
Sum up the values in onbe line and show the sum
And in the resulting code, we will do exactly that.
So, first, we open the file, and check, it it could be opened. Then, in a simple for loop, we read all lines that are present in the source code. Line by line.
In the body of the for loop, we take the current line that we just read, and put it into an std::istringstream. We do that to make extraction of the integer value simpler. And for the extraction, we use the std::istream_iterator. This will iterate over all integers in the line and return them.
We will store the values temporary in a std::vector. We use the range constructor of the std::vector. The begin iterator is the std::istream_iterator for the data type int and and for our std::istringstream. The end iterator is the default constructed std::istream_iterator, so, simply {}. This will copy all values into the std::vector
That is a powerful and compact on-liner.
We copy the values in the std::vector, so, the integer values of one line to the console.
Then, we add up all values in the std::vector (all integers from one line) and show the result on the screen.
And the beauty of it: It doesn't matter, how many rows and columns are present. It will work always. The only thing we need is space separated integer values in lines.
And all this can be done with just 7 statements . . .
Please see:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>
int main() {
// Open file and check, if it could be opened
if (std::ifstream csv{ "col.csv" }; csv) {
// Read all lines from the source file
for (std::string line{}; std::getline(csv, line); ) {
// Put the current line in a stringstream for better extraction
std::istringstream iss{ line };
// Exctract all integer values from this line and put them int a vector
std::vector values(std::istream_iterator<int>(iss), {});
// Show values on display
std::copy(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, " "));
// Claculate the sum for one line on show on display.
std::cout << " --> " << std::accumulate(values.begin(), values.end(), 0) << '\n';
}
}
else std::cerr << "\n*** Error: Could not open 'col.csv'\n";
return 0;
}
Language is C++ 17

hardcoding 2D array values

Trying to insert values into a 2D array, but the output isnt giving my values, instead random letters
int myArr[8][2] = {700,730,760,790,810,840,910,1000}{0.011,0.035,0.105,0.343,0.789,2.17,20,145};
cout << myArr << endl;
system("Pause");
How should I adjust the code, or is it easier to use a text file and insert?
Numerous problems:
the array dimensions are wrong
you don't have outer braces or a comma for the nested arrays
you're trying to store double precision floating point values in an int array
you can't use cout with an entire array.
The array declaration should probably be something like this:
double myArr[2][8] = { {700,730,760,790,810,840,910,1000},
{0.011,0.035,0.105,0.343,0.789,2.17,20,145} };
and to output the contents you could do something like this:
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 8; ++j)
{
cout << " " << myArr[i][j];
}
cout << endl;
}
Live Demo
First - you can't print the whole array just by using cout << myArr, you need to iterate over the elements of the array using a for loop.
Second - you are trying to put decimal values into an integer array which will truncate all of the decimals.
Third - Your array should be sized myArr[8][2] not myArr[2][8]. I'm surprised your compiler lets you get away with this. You should probably look into using a different compiler.
You need to iterate through each row and column, otherwise you're just printing out the pointer value of the array handle.
for (int i=0;i<8;i++){
for (int j=0;j<2;j++){
cout << myArr[i][j] << " ";
}
cout << endl;
}
system("Pause");

Output from array is wrong

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
using namespace std;
void make_array(ifstream &num, int (&array)[50]);
int main(){
ifstream file; // variable controlling the file
char filename[100]; /// to handle calling the file name;
int array[50];
cout << "Please enter the name of the file you wish to process:";
cin >> filename;
cout << "\n";
file.open(filename);
if(file.fail()){
cout << "The file failed to open.\n";
exit(1);
}
else{
cout << "File Opened Successfully.\n";
}
make_array(file, array);
file.close();
return(0);
}
void make_array(ifstream &num, int (&array)[50]){
int i = 0; // counter variable
while(!num.eof() && i < 50){
num >> array[i];
i = i + 1;
}
for(i; i>=0; i--){
cout << array[i] << "\n";
}
}
Alright, so this it my code so far. When I output the contents of the array, I get two really large negative numbers before the expected output. For example, if the file had 1 2 3 4 in it, my program is outputting -6438230 -293948 1 2 3 4.
Can somebody please tell me why I am getting these ridiculous values?
Your code outputs the array backwards, and also it increments i twice after it has finished reading all the values. This is why you see two garbage values at the start. I suspect you are misreporting your output and you actually saw -6438230 -293948 4 3 2 1.
You end up with the extra increments because your use of eof() is wrong. This is an amazingly common error for some reason. See here for further info. Write your loop like this instead:
while ( i < 50 && num >> array[i] )
++i;
Now i holds the number of valid items in the list. Assuming you do actually want to output them backwards:
while ( i-- > 0 )
cout << array[i] << "\n";
To output them forwards you'll need two variables (one to store the total number of items in the array, and one to do the iteration)
The check !num.eof() only tells you that the last thing you read was not eof. So, if your file was 1 2 3 4, the check will only kick in after the 5th num>>array[i] call. However, for that i, array[i] will be populated with a meaningless value. The only correct way to deal with eofs is to check for validity on every call to operator>>. In other words, the right condition is simply num>>array[i]. This works by exploiting this conversion to bool since C++11 and to void* pre-C++11.

C++ file writing/reading

I'm trying to create an array, write array to the file and than display it. It seems to be working but i get just part of the output (first 3 elements) or i get values over boundaries.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int arr[20];
int i;
for (i = 0; i < 5; i++)
{
cout << "Enter the value to the array: " << endl;
cin >> arr[i];
}
ofstream fl("numbers.txt");
if (!fl)
{
cout << "file could not be open for writing ! " <<endl;
}
for (i = 0; i < arr[i]; i++)
{
fl<<arr[i]<<endl;
}
fl.close();
ifstream file("numbers.txt");
if(!file)
{
cout << "Error reading from file ! " << endl;
}
while (!file.eof())
{
std::string inp;
getline(file,inp);
cout << inp << endl;
}
file.close();
return 0;
}
The terminating condition in the for loop is incorrect:
for(i=0;i<arr[i];i++)
If the user enters the following 5 ints:
1 0 4 5 6
the for loop will terminate at the second int, the 0, as 1 < 0 (which is what i<arr[i] would equate to) is false. The code has the potential to access beyond the bounds of the array, for input:
10 11 12 13 14
the for loop will iterate beyond the first 5 elements and start processing unitialised values in the array arr as it has not been initialised:
int arr[20];
which could result in out of bounds access on the array if the elements in arr happen to always be greater than i.
A simple fix:
for(i=0;i<5;i++)
Other points:
always check the result of I/O operations to ensure variables contain valid values:
if (!(cin >> arr[i]))
{
// Failed to read an int.
break;
}
the for loop must store the number of ints read into the arr, so the remainder of the code only processes values provided by the user. An alternative to using an array, with a fixed size, and a variable to indicate the number of populated elements is to use a std::vector<int> that would contain only valid ints (and can be queried for its size() or iterated using iterators).
while (!file.eof()) is not correct as the end of file flag will set only once a read attempted to read beyond the end of the file. Check the result of I/O operations immediately:
while (std::getline(file, inp))
{
}
its like hmjd said
for(i=0;i<arr[i];i++)
looks wrong
it should look like this
int size;
size=sizeof(your array);
for(i=0;i<size;i++)
Try this:
//for(i=0;i<arr[i];i++)
for(i=0;i<5;i++)
[EDITED]
I would initialize the array with 0 like this: int arr[20] = {0}; In this case you can use for example:
while ((arr[i] != 0 || i < sizeof(arr))
i<array[i]
It is wrong beacuse it comapres with the content of the array ,it does not check the size of array .