C++ file stream, copy data from .dat file to vector - c++

I have a .dat file containing full of integers 100 by 100, and I am trying to transfer x rows and x columns into a new vector, I've managed to ge the first row with the desired columns but stuck in trying to get to the next line and until to the x rows, please give help. This is my code so far
also some help on the display part, I'm not sure how to display a vector with more than one rows and columns. Tried data.at(i).at(j) double for loop but unsuccessful
//variable
int row, col;
string fname;
ifstream file;
vector<int> data;
//input
cout << "Enter the number of rows in the map: "; cin >> row;
cout << "Enter the number of columns in the map: "; cin >> col;
cout << "Enter the file name to write: "; cin >> fname;
//open file
file.open(fname, ios::in); // map-input-100-100.dat
int temp;
for (int i = 0; i < col; ++i)
{
file >> temp;
data.push_back(temp);
}
// display first row of data
for (int i = 0; i < data.size(); ++i) cout << data.at(i) << ' ';
cout << endl;

The code could be like this:
vector<vector<int>> data; // instead of your definition of data:access data[r][c]
for (int j = 0; j < row; ++j)
{
vector<int> x(column);
for (int i = 0; i < col; ++i)
{
file >> temp;
x[i] = temp;
}
data.push_back(x);
}

Related

How can i find the index of the largest value input in a 2d array C++

I need help in trying to find the index of the largest element. The user first enters the size of the 2d array, then the user inputs the elements in an array. Then the program would display the location of the largest array.
However, I have this code below and am having trouble in printing out the index location of the largest element in the array. It just returns as 0,0.
#include<iostream>
using namespace std;
int main()
{
int row, column;
int r,c;
cout << "Enter the number of rows of the array: ";
cin >> row;
cout << "Enter the number of column of the array: ";
cin >> column;
cout << "\nEnter the array: " << endl;
double table[row][column];
for ( r = 0; r < row; r++) {
for ( c = 0; c < column; c++) {
cin >> table[row][column];
}
}
int rr=0,cc=0;
int max;
for ( r = 0; r < row; r++){
if (table[rr][cc] < table[r][c]) {
rr=r;}
for ( c = 0; c <column; c++){
if (table[rr][cc] < table[r][c]) {
cc=c;
}
}
}
cout << "\nLocation of the largest array: " << rr << ","<< cc << endl;
}
You should first move r and c to search for the satisfying element, and then check if the elements satisifies the condition.
for ( r = 0; r < row; r++){
// remove this, or you will access out-of-range because c will be column here
//if (table[rr][cc] < table[r][c]) {
// rr=r;}
for ( c = 0; c <column; c++){
if (table[rr][cc] < table[r][c]) {
rr=r; // also update rr here
cc=c;
}
}
}
Also, as #Jarod42 pointed out, the input part cin >> table[row][column]; is also wrong. It should be cin >> table[r][c];, or another out-of-range access will be invoked there.

2D integer array in c++ with uneven number of elements in each row

The number of rows and columns of this array are given by the user however the number of rows are not the same (the array is uneven) and also the user will fill the array by entering the elements.
This is the code that I wrote but when I try to take input from user, the code crashes after taking some inputs. Please could you help me out and correct my code and point my flaws. Thank you.
#include <iostream>
//2d array
using namespace std;
int main()
{
int row;
int col_x;
cout << "Enter the row number:" << endl;
cin >> row;
//cout<<"Enter the column number:"<<endl;
//cin>>col;
int **a = new int *[row];
for (int r = 0; r < row; r++)
{
cout << "Enter the column no.of array " << r << endl;
cin >> col_x;
a[r] = new int[col_x];
cout << "Enter the elements in the array:" << endl;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col_x; j++)
{
cin >> a[i][j];
}
}
cout << "The elements in the array:" << endl;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col_x; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
}
delete[] a;
a = NULL;
return 0;
}
There was an extra for loop. Also, you have to store the size of each row.
And make the proper deallocation of the 2D array.
#include <iostream>
//2d array
using namespace std;
int main()
{
int row;
cout<<"Enter the row number:"<<endl;
cin>>row;
int **a=new int *[row];
int *col_x = new int [row];
for(int r=0;r<row;r++){
cout<<"Enter the column no.of array "<<r<<endl;
cin>>col_x[r];
a[r]=new int[col_x[r]];
cout<<"Enter the elements in the array:"<<endl;
for(int j=0;j<col_x[r];j++){
cin>>a[r][j];
}
}
cout<<"The elements in the array:"<<endl;
for(int i=0;i<row;i++){
for(int j=0;j<col_x[i];j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
for (int i=0; i<row; ++i)
delete[] a[i];
delete []a;
delete []col_x;
return 0;
}
The way you are getting the input from the user is very vague, and is prone to accessing invalid memory. You are getting the same row many times in the inner loop.
Try something like this:
#include <iostream>
//2d array
using namespace std;
int main() {
int row;
int col_x;
cout << "Enter the row number:" << endl;
cin >> row;
//cout<<"Enter the column number:"<<endl;
//cin>>col;
int ** a = new int * [row];
for (int r = 0; r < row; r++) {
cout << "Enter the column no.of array " << r << endl;
cin >> col_x;
a[r] = new int[col_x];
cout << "Enter the elements in the array:" << endl;
for (int j = 0; j < col_x; j++) {
cin >> a[r][j];
}
}
cout << "The elements in the array:" << endl;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col_x; j++) {
cout << a[i][j] << " ";
}
cout << endl;
}
delete[] a;
a = NULL;
return 0;
}
Also, note that col_x will hold only the size of the last row. So, it's not working for the printing at the end of the code.
Not sure what you are trying to achieve, but the main issue with above code is, that you are accessing non-existing elements of your array. Maybe your loop over r should end in line 18? Even then, you would have to store the number of columns per row in some external variable. I would suggest to use a std::vector as the container instead of fixed arrays, in your case a std::vector< std::vector<int> >. The vector class has a method size() which stores its actual size.
Since you are using C++, you should take advantage of the containers it provides for you to store your data, in this case a vector of vectors would be appropriate:
Live Sample
#include <iostream>
#include <vector>
using namespace std; //<-- for test, souldn't be used
int main() {
int rows, cols, temp;
vector<vector<int>> matrix;
cout << "Enter the row number:" << endl;
cin >> rows;
for (int i = 0; i < rows; i++){
vector<int> v;
cout << "Enter the column no.of array " << i << endl;
cin >> cols;
cout << "The elements in the array:" << endl;
for (int j = 0; j < cols; j++){
cin >> temp;
v.push_back(temp);
}
matrix.push_back(v);
}
cout << endl;
for( auto i: matrix){ //print results
for(int j: i)
cout << j << " ";
cout << endl;
}
}

Read everything up to a whitespace from a text file

(C++) I've created a function to open the text file and assign the contents to an array. The first 2 elements in the array are the size of the grid. However, if either or both of the first 2 numbers are double digits, it doesnt read them in as double digits. Is there any way of doing this?
int openMap()
{
std::string fileName;
std::cout << "Please enter the file name with extension that you want to open: ";
std::cin >> fileName;
system("CLS");
std::ifstream file(fileName); //OPENS MAP FILE
int tmp;
int i = 0;
if (!file.is_open()) //CHECKS IF THE MAP FILE HAS OPENED CORRECTLY
{
std::cout << "Error Occured!\nCould not open file.";
return 0;
}
while (!file.eof()) //READS THE MAP FILE AND PASSES THE INFORMATION INTO AN ARRAY
{
file >> tmp;
checkNumber(tmp);
if (valid == true) //IF THE CHARACTER IS NOT A NUMBER THEN IT WONT BE PASSED INTO THE ARRAY
{
tmpArray[i] = tmp;
i++;
valid = false;
}
row = tmpArray[1]; //ASSIGNS THE FIRST 2 NUMBERS OF THE MAP FILE TO ROW AND COL VARIABLES
col = tmpArray[0];
}
return row, col;
}
I would assume I have to rewrite
file >> tmp
in some sort of different way, but not sure how.
Is there a way to scan through the text file until it hits a whitespace?
The text file contents looks like this
6 4 0 0 1 0 0 0 2 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 3 0
(the 6 or 4 or both can be double digits instead)
Edit:
for (int j = 0; j < row; j++)
{
for (int k = 0; k < col; k++)
{
_map[j][k] = tmpArray[l];
std::cout << _map[j][k] << " ";
l++;
}
}
There's quite a number of bugs in the code, you should probably use a debugger to step through and identify which parts of your program don't behave as expected.
while(!file.eof())
file >> tmp;
checkNumber(tmp);
if (valid == true) //IF THE CHARACTER IS NOT A NUMBER THEN IT WONT BE PASSED INTO THE ARRAY
{
tmpArray[i] = tmp;
i++;
valid = false;
}
row = tmpArray[1]; //ASSIGNS THE FIRST 2 NUMBERS OF THE MAP FILE TO ROW AND COL VARIABLES
col = tmpArray[0];
You set row=tmpArray[1] and col = tmpArray[0] every iteration of the loop which is not only unnecessary but also incorrect, especially since row=tmpArray[1] is being executed at i=0 when nothing has been placed in tmpArray[1] yet.
EDIT: This is a lot smaller, less error prone due to less variables and type conversions, and easier to read:
int row,col;
//Add error checking here
cin >> col;
cin >> row;
cout << "Cols: " << col << " Rows: " << row << endl;
vector<vector<int> >_map(row, vector<int>(col,0));
for(int j=0; j < row; j++)
{
for(int k=0; k < col; k++)
{
int tmp;
cin >> tmp;
//Add error checking for tmp
_map[j][k] = tmp;
cout << _map[j][k] << endl;
}
}
There are some problems with your code. First the return type of your function is int but you are returning multiple values. Here is a complete running code which should solve your problem.
#include <iostream>
#include <fstream>
#include <vector>
std::vector< std::vector<int> > openMap() {
std::string fileName;
std::cout << "Please enter the file name with extension that you want to open: ";
std::cin >> fileName;
std::fstream myfile(fileName, std::ios_base::in);
int row, col;
myfile >> row;
myfile >> col;
int a;
std::vector< std::vector<int> > retval;
for (int i = 0; i < row; i++) {
std::vector<int> v1;
for (int j = 0; j < col; j++) {
myfile >> a;
v1.push_back(a);
}
retval.push_back(v1);
}
return retval;
}
int main(int argc, char * argv[])
{
std::vector< std::vector<int> > _map = openMap();
for(int i = 0; i < _map.size(); i++) {
for (int j = 0; j < _map[i].size(); j++) {
std::cout << _map[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}
I guess that not so many people will be interested. But please see below a possible solution to your problem.
The code uses modern C++ algorithms.
It is very simple and straightforward.
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
int main() {
// Ask user, to give a filename
std::cout << "Please enter the file name with extension that you want to open: ";
// Get the filename from the user
if (std::string fileName; std::cin >> fileName) {
// Open the file and check, if it is open
if (std::ifstream sourceFile(fileName); sourceFile) {
// Read the number of rows and columns of the matrix
if (size_t numberOfColumns, numberOfRows; sourceFile >> numberOfColumns >> numberOfRows) {
// Create a matrix with the given number of rows and columns
std::vector<std::vector<int>> result(numberOfRows, std::vector<int>(numberOfColumns, 0));
// Read data from the input stream and put it into the matrix
for (size_t i = 0; i < numberOfRows; ++i) {
std::copy_n(std::istream_iterator<int>(sourceFile), numberOfColumns, result[i].begin());
}
// Print result. Go through all lines and then copy line elements to std::cout
std::for_each(result.begin(), result.end(), [](std::vector<int>& c) {
std::copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "\n"; });
}
}
else {
std::cerr << "\n*** Error: Could not open source File\n\n";
}
}
return 0;
}

How to open a file in Sudoku?

I am trying to write a program for Sudoku. The Sudoku runs well for my input file. But I want to make some changes that input the file in the compiler. It catches the error like no matching member function for call to 'open'. This is just part of my program because I think my problem is the I/O file. Any help is appreciated! Thanks you!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <string>
using namespace std;
int main()
{
char filename;
ifstream myfile;
//int row,column;
int choice;
cout << "Enter the desired sudoku 4 for (4x4) or 9 for (9x9) : \n";
cin >> choice;
if(choice == 9) {
for(int row = 0; row < 9; row++) // iterating the loop to assign initial dummy values
{
for(int column = 0; column < 9; column++)
{
sudoku[row][column] = 0; // assigining zeros
}
}
cout << "Enter the filename:" << endl;
cin >> filename;
myfile.open(filename); // opening the file mentioned
cout << "The values in the file are :" << endl;
if (myfile.is_open())
{
while (!myfile.eof())
{
for(int row = 0; row < 9; row++) // iterating the loope to get the values form the file
{
for(int column = 0; column < 9; column++)
{
myfile >> sudoku[row][column]; // assigning the values to the grid
cout << sudoku[row][column] << endl; // printing the grid
}
}
}
}
myfile.close(); // closing the file
solvesudoku(0,0);//We start solving the sudoku.
}
else if(choice == 4) {
for(int row = 0; row < 4; row++) // iterating the loop to assign initial dummy values
{
for(int column = 0; column < 4; column++)
{
sudoku1[row][column] = 0; // assigining zeros
}
}
cout << "Enter the filename:" << endl;
cin >> filename;
myfile.open(filename); // opening the file mentioned
cout << "The values in the file are :" << endl;
if (myfile.is_open())
{
while (!myfile.eof())
{
for(int row = 0; row < 4; row++) // iterating the loope to get the values form the file
{
for(int column = 0; column < 4; column++)
{
myfile >> sudoku1[row][column]; // assigning the values to the grid
cout << sudoku1[row][column] << endl; // printing the grid
}
}
}
}
myfile.close(); // closing the file
solsudoku(0,0);//We start solving the sudoku.
}
else {
cout << "Invalid Choice..!!!";
}
return 0;
}
Your filename variable has type char. That is a single integral value that can store one "character".
The compiler is correct when it says that no fstream constructor takes a filename of type char.
You probably meant char[SOME_BUFFER_SIZE], or ideally std::string.
Note that if you use std::string and you move to a C++03 compiler, you'll have to append c_str() when you pass it to the fstream, for historical reasons.

Read line of numbers from stdin [duplicate]

This question already has answers here:
How to determine if a string is a number with C++?
(36 answers)
Closed 8 years ago.
I am working on program that would calculate with matrixes but i am not sure what is best way how to read matrix line by line from command line.
My goal is this:
Please enter number of lines:
2
Please enter line 1/2:
1 4 5 2
Please enter line 2/2:
1 5 7 8
At the end of this i would like to have array or vector of numbers 1,4,5,2,1,5,7,8.
This is my code:
vector<string>matrix;
string input;
int nrows;
cout << "Enter number of rows:" << endl;
cin >> nrows;
getline(cin, input);
for (int i = 1; i <= nrows; i++) {
cout << "Enter line " << i << "/" << nrows << endl;
getline(cin, input);
matrix.push_back(input);
}
for (int i = 0; i < matrix.size();i++){
cout << matrix.at(i)<<endl;
}
This reads whole line and save it into vector of string and there is much to do to separate just numbers. Is there any way how could I load only numbers in the line ? So for example for the line:
1 a 3 2 4sdsd
I would get numbers 1,3,2,4 ?
Thank for any help.
string process(const string& input) // Removes all characters except <space> and digits [0-9]
{
string ret;
for(int i=0; i<(int)input.size(); i++)
{
if(input[i]==' '||(input[i]>='0'&&input[i]<='9'))
ret+=input[i];
}
return ret;
}
int main()
{
int nrows;
string input;
cout<<"Enter number of rows - ";
cin>>nrows;
cin.get(); // Take the remaining <Enter>
vector<vector<int> > matrix(nrows); // A 2-D vector representing the matrix
for(int i=0; i<(int)matrix.size(); i++)
{
cout<<"Please enter line "<<i+1<<"/"<<nrows<<" -: \n";
getline(cin,input);
stringstream ss(process(input));
int num;
while(ss>>num)
{
matrix[i].push_back(num);
}
}
for(int i=0; i<(int)matrix.size(); i++) // Display the matrix
{
for(int j=0; j<(int)matrix[i].size(); j++)
{
cout<<matrix[i][j]<<" ";
}
cout<<"\n";
}
}
I would use a 2D vector. Also, ask the user for number of columns:
vector<vector<int>> matrix;
int nrows, ncols;
cout << "Enter number of rows:" << endl;
cin >> nrows;
cout << "Enter number of columns:" << endl;
cin >> ncols;
matrix.resize(nrows);
for (int i = 0; i < nrows; i++) {
cout << "Enter line " << (i+1) << "/" << nrows << endl;
int tmp;
while (matrix[i].size() < ncols) {
while (!(cin >> tmp)) { // Not a number. Clear cin
cin.clear();
cin.ignore(1);
}
matrix[i].push_back(tmp);
}
}
One way to do it:
// only allow digits and spaces
string removeNonNumbers(const string& s) {
stringstream ss;
for(int i=0; i<s.length(); ++i) {
if(isdigit(s[i]) || ' ' == s[i])
ss << s[i];
}
return ss.str();
}
vector<int> splitToInts(const string& s) {
vector<int> ret;
stringstream ssin(s);
while (ssin.good()){
string tmp;
ssin >> tmp;
ret.push_back(atoi(tmp.c_str()));
}
return ret;
}
To use it, do this when reading input in your getline loop:
vector<int> numbers = splitToInts( removeNonNumbers(input) );