I am trying to write a c++ program to read a txt file containing data (122X300 matrix - tab delimited matrix) into my code and get it to display. The following is the code I wrote after referring extensively to google and many similar questions on this site. On running the code, I do not get any errors, however it does give me huge list of numbers which I cant seem to make any sense of. The following is the code: Any help would be great. I do not know where I am going wrong. Thanks.
DID some changes after considering the comment below by #ZekeMarsh, the problem now is that my text data is like:
Data Matrix Snapshot
The output I am getting is this:
Output of Code
The row counter does not move over to the next row,instead continues in the same row after incrementation....No idea why. The code modified is as follows:
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
using namespace std;
int main(){
int HEIGHT = 3;
int WIDTH = 2;
int array_req[HEIGHT][WIDTH];
string userinputprompt, filename;
userinputprompt = "Data Filename: ";
cout<<userinputprompt<<endl;
getline(cin,filename);
ifstream inputfile;
inputfile.open(filename.c_str());
for(int i=0; i<HEIGHT; i++)
{
for(int j=0; j<WIDTH; j++)
{
/*if(!(inputfile>>array_req[i][j]))
{
cerr<<"Error";
break;
}
else if(!inputfile) // its error.. , can use a cerr here...
{
cerr<<"Error";
break;
}
else*/
inputfile>>array_req[i][j];
cout<<i<<","<<j<<"-->"<<array_req[i][j]<<endl;
}
/* This is not needed, read above comment
else
{
inputfile >> array_req[i][j];
}*/
}
for(int p=0; p<HEIGHT; p++)
{
for(int q=0; q<WIDTH; q++)
{
cout<<array_req[p][q]<<" ";
}
cout<<"\n";
}
inputfile.close();
getchar();
return 0;
}
.
EDITED CODE - The output array is a null matrix. Please help. What is wrong in the code ..compiles correctly. Trying to read line by line using getline and stringstream based on a lot of examples I read here..still not working.
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include <sstream>
#include <stdlib.h>
const int HEIGHT = 3;
const int WIDTH = 4;
const int BUFFSIZE = 10000;
using namespace std;
int main(){
int array_req [HEIGHT][WIDTH];
char buff[BUFFSIZE];
string userinputprompt, filename;
userinputprompt = "COLORDATA FILENAME: ";
cout<<userinputprompt<<endl;
getline(cin,filename);
ifstream inputfile;
stringstream ss;
inputfile.open(filename.c_str());
for (int i=0; i<HEIGHT; i++)
{
inputfile.getline(buff,BUFFSIZE,'\n');
ss<<buff;
for(int j=0;j<WIDTH; j++)
{
ss.getline(buff,1000,'\n');
array_req[i][j]=atoi(buff);
}
ss<<"";
ss.clear();
}
for(int p=0; p<HEIGHT; p++)
{
for(int q=0; q<WIDTH; q++)
{
cout<<array_req[p][q]<<" ";
}
cout<<"\n";
}
inputfile.close();
getchar();
return 0;
}
First of all during the printing of your array, you are not delimiting your data with anything which will result in a line of numbers. You should add delimiter and line breaks.
Second and most importantly: you try printing the full value of the array while it has not been filled up yet. I believe you meant to put the printing outside of the loop that works with your variable i . Now you are printing garbage in the places where the array was not filled yet.
Edit: Here is only the reading part as I believe that is only what you are looking for:
for (int i = 0; i < HEIGHT; ++i)
{
std::string tmpString;
std::getline(inputfile, tmpString);
std::stringstream ss(tmpString);
for(int j=0;j < WIDTH; ++j)
{
ss >> array_req[i][j];
}
}
Related
For this project, we are supposed to use an input and output file to better organize our data. Howvever, for whatever reason, every time I rube the program it says
"File couldn't open. Terminating.
Process finished with exit code 1"
I have tried several different methods to try and get the program to open the file (using different commands, changing filename, etc), however each time it gives me the above statement.
Here is the code for my program (please note there is much more code than this. However, this is the only area that uses the input file, so I am confident that the error is residing somewhere withing here):
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>
#include <limits>
#ifdef _MSC_VER // Memory leak check
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#define VS_MEM_CHECK _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#else
#define VS_MEM_CHECK
#endif
using namespace std;
const int NUM_GRADES = 5;
int main(int argc, char* argv[]) {
VS_MEM_CHECK // Enable memory leak check
ifstream inputFile; // Reading Input file
inputFile.open(argv[1]);
if (inputFile.is_open()) { // Checks if file opened succesfully
cout << "Input File opened successfully.\n";
} else {
cout << "File couldn't open. Terminating.\n";
return 1;
}
int numStudents;
int numExams;
inputFile >> numStudents >> numExams;
inputFile.ignore(std::numeric_limits<int>::max(), '\n');
string *arrayNames = new string[numStudents]; // Intializes Students Array
double *arrayTotalGrade = new double[numStudents]; // Initializes Total Score Array
double *arrayAverages = new double[numExams]; // Initializes Average Score Array
int **arrayScores = new int *[numStudents]; // Initializes Scores Array
for (int i = 0; i < numStudents; ++i) {
arrayScores[i] = new int[numExams];
}
int **arrayGradeCount = new int *[numExams]; // Initializes Grade Count Array
for (int i = 0; i < numExams; ++i) {
arrayGradeCount[i] = new int[NUM_GRADES];
for (int j = 0; j < NUM_GRADES; ++j) {
arrayGradeCount[i][j] = 0;
}
}
for (int i = 0; i < numStudents; ++i) {
string line;
string name;
getline(inputFile, line);
size_t p = 0;
while (!isdigit(line[p])) ++p; // line[p] is the location of the first digit on the line
name = line.substr(0, p - 1); // Gets name from file, p-1 removes an extra whitespace.
arrayNames[i] = name;
line = line.substr(p); // Isolates scores on line
istringstream iss(line); // Puts line (now with only scores' values) into an istringstream
for (int j = 0; j < numExams; ++j) // Puts scores from istringstream into arrayScores onto row 'i'
{
int scores;
iss >> scores;
arrayScores[i][j] = scores;
}
}
inputFile.close();
}
For a project I am currently working on, I have to read from a file and depending on the certain character in the file, output either a 1 or 0 to an array.
So here is an example of file input:
* * *
* * *
** ** **
*** *
And here is the function I have written to handle this:
void input (int cellGrid[][MAX]) //takes info from a .txt and puts it into an array
{
ifstream infile; //declare a file variable
int row;
int column;
int number;
infile.open("life.txt"); //open a file
while(infile>>row>>column) { //inserts bacteria places into array
cout << row << " " << column << endl;
cellGrid[row][column]=1; //makes it equal one if bacteria is present
}
infile.close(); //closes file
}
My thinking was that the function needs to see if there is a character that exists and if so, place a 1 in its respective position ([row][column]) in the array. However with this current code, nothing is input into my array.
Generally in C++ use std::vector wherever possible.
Array example:
You have to go through the file and record position of each *. Then set it to 1 for that position. Something like the following (we use getline and i as counter for rows, then we loop through the line using j as counter for columns):
#include <fstream>
#include <string>
using namespace std;
void input(int cellGrid[][100]) {
ifstream infile;
infile.open("life.txt");
int i = 0;
for (string line; getline(infile, line); ++i)
{
for (size_t j = 0; j < line.size(); ++j) {
if (line[j] == '*') {
cellGrid[i][j] = 1;
}
}
}
infile.close();
}
Vector example #1:
Here you can find a solution using std::vector. It will be always in a size rows x columns. One thing it requires is to pass default constructed vector and not constructed with vector(size_type count); c-tor. You can write your own version that doesn't have this problem:
#include <fstream>
#include <string>
#include <vector>
using namespace std;
void input(vector<vector<int>> &cellGrid) {
ifstream infile;
infile.open("life.txt");
int i = 0;
for (string line; getline(infile, line); ++i)
{
cellGrid.push_back(vector<int>(line.size()));
for (size_t j = 0; j < line.size(); ++j) {
if (line[j] == '*') {
cellGrid[i][j] = 1;
}
}
}
infile.close();
}
int main() {
vector<vector<int>> cellGrid;
vector<vector<int>> cellGrid2(100);
input(cellGrid);
//input(cellGrid2); - THIS WILL THROW AN EXCEPTION
return 0;
}
Vector example #2:
It would be even better for you function to return a newly created and populated vector:
#include <fstream>
#include <string>
#include <vector>
using namespace std;
vector<vector<int>> input() {
ifstream infile;
infile.open("life.txt");
vector<vector<int>> cell_grid;
int i = 0;
for (string line; getline(infile, line); ++i)
{
cell_grid.push_back(vector<int>(line.size()));
for (size_t j = 0; j < line.size(); ++j) {
if (line[j] == '*') {
cell_grid[i][j] = 1;
}
}
}
infile.close();
return cell_grid;
}
int main() {
auto vec = input();
return 0;
}
My thinking goes like this:
set row to 0
while can read a line from file
set column to 0
for each character on line
if character is '*'
set cellGrid(row,column) to 1
else
set cellGrid(row,column) to 0
increment column
increment row
You may want additional logic to trap row or column trying to go out of bounds or characters that aren't ' ' or '*'.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdio>
#include <stdlib.h>
using namespace std;
int gradeExam(string answerKeyARR[]);
int main()
{
const int QUESTIONS = 10;
const int MAX_STUDENTS = 250;
ifstream inFile;
ofstream outFile;
inFile.open("grade_data.txt");
outFile.open("grade_report.txt");
string ansKey;
inFile >> ansKey;
string answerKeyARR[QUESTIONS];
//Loop for storing each answer into an array rather than all in a single string.
for (int j = 0; j < QUESTIONS; j++)
{
answerKeyARR[j] = ansKey.substr(j,1);
}
int i = 0;
int numStudents = 0;
string studentAnswers[MAX_STUDENTS];
//Loop to read in all answers into array and count number of students.
while (!inFile.eof())
{
inFile >> studentAnswers[i];
numStudents++;
i++;
}
//WHY DOES IT CRASH HERE?!
string studentAnswersARR[numStudents][QUESTIONS];
for (int k = 0; k < numStudents; k++)
{
for (int l = 0; l < QUESTIONS; l++)
{
studentAnswersARR[k][l] = studentAnswers[l].substr(l,1);
cout << studentAnswersARR[k][l];
}
}
inFile.close();
outFile.close();
return 0;
}
Okay, so basically once it gets to the part where it's removing the substring, it crashes. It works perfectly fine for retrieveing the answerkey answers, so why the hell is it crashing when it gets to this point? This is still a WIP for basic coding 2.
Also, when I change variable 'l' to, say, position 0, it works. What gives?
There are multiple issues with your code that may cause problems.
First, your input loop is not bounded properly. It should stop at MAX_STUDENTS, but you fail to check for this limit.
Second, do not use eof() to check for the end of file. There are many posts on SO discussing this.
while (!inFile && i < MAX_STUDENTS)
{
inFile >> studentAnswers[i];
numStudents++;
i++;
}
The next issue is the line you highlighted in your question. It probably crashes due to stack space being exhausted. But the code you have uses a non-standard C++ extension, and once you do that, then the rule as to what that line really does internally is up to the compiler vendor.
So to alleviate this with using standard C++, the following can be done:
#include <vector>
#include <string>
#include <array>
//...
std::vector<std::array<std::string, QUESTIONS> >
studentAnswersARR(numStudents);
Here is my solution to the problem in the codeforces http://codeforces.com/problemset/problem/499/B . I am facing problem in inputting the string. It termintes after line 10 (see code) before i give input str to it and output some weird chars.
Input: 4 3
codeforces codesecrof
contest round
letter message
Output:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
int main(){
int N, M;
string str;
cin>>N>>M;
string A[M], B[M];
for(int i=0; i<M; i++)
cin>>A[i]>>B[i]; // line 10
getline(cin,str);
char res[N+1];
for(int i=0; i<M; i++){
int j= str.find(A[i]);
int k;
int x=0;
if(B[i].length() < A[i].length()){
for(k=j; k<B[i].length(); k++){
res[k]= B[i][x];
x++;
}
}else{
for(k=j; k<B[i].length(); k++){
res[k]= B[i][x];
x++;
}
}
res[k]=' ';
}
for(int i=0; i<=N; i++ )
cout<<res[i];
cout<<endl;
return 0;
}
There is a newline character left in the input stream after:
cin>>N>>M;
You need a line of code that will read and discard the rest of the line. Add a line;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
after that line.
Add
#include <limits>
to be able to use std::numeric_limits.
I'm trying to read numbers from a test file and display them in a matrix. In the text file, there is one number per line. The first two lines are the dimensions of the matrix.(3 and 4) I'm having trouble assigning the actual data values of these numbers to the matrix. In this case Values 2 through 14.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
#include "Matrix.h"
int main()
{
CMatrix A(10,10); //set to arbitrary size
int x;
int i = 0;
int number;
int rowsFile;
int columnsFile;
while ( myFile.good()&& myFile.is_open() )
{
myFile>>x;
if (i==0){ //for row dimension
rowsFile = x;
}
if (i==1){ //for column dimension
columnsFile = x;
}
cout<<"Value "<<i<<": "<<x<<endl; //displays the values
if (i>=2){
for (int r = 0; r < rowsFile; r++)
{
for (int c = 0; c < columnsFile; c++)
{
A.Value(r,c) = x;
myFile>>x;
}
}
myFile.close();
}
i=i+1;
}
myFile.close();
CMatrix A(rowsFile, columnsFile);
cout<<endl<< "Rows: "<<A.getNumberOfRows()<<endl;
cout<< "Columns: "<<A.getNumberOfColumns()<<endl;
cout<<endl<<A.ToString();
}
Here is a display of my output.
For some reason my commented out loop doesn't seem to be working.
Any help would be appreciated. Thank you!
While I can't offer you a complete solution due not completely understanding what you're trying to do, I recommend reading the contents of the file line wise and storing them in a vector, as in this example:
std::ifstream ifs("file.txt");
std::string line;
std::vector<std::string> lines;
if (ifs.good()) while (getline(ifs, line)) lines.push_back(line);
else throw std::runtime_error("An error occurred while trying to read from file.");
This makes it easier to work with the data.
I suggest you reorganize this code to place doubles into matrix elements immediately after reading them.
The file io code may not be perfect, but I would separate the reading of the number of rows and columns from the loop that handles the element values.
// do not declare i here
int numRows;
int numCols;
std::fstream inputFile("filename", std::in);
if ! (inputFile >> numRows >> numCols)
{
// Handle error
}
// Check that numRows and numCols are acceptable (positive)
// [not shown]
CMatrix A(numRows, numCols);
if (inputFile)
{
int elementsRead = 0;
for (int i = 0; i < numRows; i++)
{
for (int j = 0; j < numCols; j++)
{
double x;
if (inputFile >> x)
{
A.Value(i,j) = x;
++elementsRead;
} else {
// probably an error from too-short file,
// token could not be converted to double, etc.
// handle appropriately
break;
}
}
}
}
if (elementsRead != numRows * numCols)
{
// handle error
}
// Use matrix A