How to read a table from .txt file to C++ - c++

I want to read a matrix from a file and use it in my program. but when I output the results, it shows that it is not reading correctly.
Here is the code:
#define I 5
#define J 5
#define P 2
int i,j,k; //for loops
int main ()
{
ifstream inFile;
ofstream outFile;
double C[I][J];
inFile.open("C.txt", ios::in);
if (! inFile) {
cerr << "unable to open file C.txt for reading" << endl;
return 1;
}
for(i=0; i<I; i++)
for(j=0; j<J; j++)
inFile >> C[i][j];
outFile.open("results.txt");
outFile<< "C" <<endl;
for(i=0;i<I;i++)
{
for(j=0;j<J;j++)
outFile<< C[i][j];
outFile<< endl;
}
inFile.close();
outFile.close();
return 0;
}
C is a matrix of integer values 2 3 5... but what I get is
316-9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061
-9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061 -9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061 -9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061 -9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061-9.25596e+061

You should output a whitespace after each number, otherwise they will be all glued together.
outFile<< C[i][j] << " ";
You also should check your input for validity. Not showing it here (you already know how to check if (! inFile)).

I suspect that you are having problems with new lines, below modification will ignore new line character after reading each line:
for(i=0; i<I; i++) {
for(j=0; j<J; j++)
inFile >> C[i][j];
inFile.ignore(); /// <<<--------
}

It seems you are writing uninitialized variables to your output file, leading to undefined behavior.
I suspect your C.txt file does not contain the 5x5 matrix your program is looking for.
You should add a simple error check, e.g.:
for(i=0; i<I; i++)
for(j=0; j<J; j++)
if (!(inFile >> C[i][j])) { /* something's wrong here */ }

Related

.txt file into 2D Char* Array

I'm fairly new to C++ and I'm working on point of sale program from a class in which I will need to read in the menu option along with the price. I'm attempting to read in a .txt file into a 2D Char* but I keep on getting the error message
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
from line containing
inFile >> array[i][j];
I'm assuming this error is arising due to the way that I'm trying to assign values to each element in the array. I'm sure how to accomplish it.
// Main function
int main (){
char *array[4][3];
string fileName;
vector<string>order;
fileName = fileLoc();
getMenu(fileName, array);
return 0;
}
string fileLoc(){
string file;
cout << "Enter file name or location: ";
cin >> file;
return file;
}
void getMenu(string fileName, char *array[][3]){
ifstream inFile(fileName.c_str());
if (!inFile){
cout << "File failed to open\n";
}
for (int i = 0; i < 4; ++i){
for (int j = 0; j < 3; ++j){
inFile >> array[i][j];
cout << array[i][j] << endl;
}
}
inFile.close();
}
The .txt file I am reading from looks like such
B Burger 3
S Soda 1
F Fries 2
C Chips 1.5

Printing out a vector produces different results every time. It also prints random code that isn't in the vector

So I am reading in a file of zeros and ones.
1,1,1,0,0,0,0,0
1,1,1,0,1,1,0,0
1,1,1,0,1,1,0,0
1,1,1,0,0,0,1,0
1,1,1,0,0,0,1,0
1,1,1,0,0,0,1,0
1,1,1,0,0,1,1,0
1,1,1,0,0,0,0,0
I read in this file and store it into a 2d vector. I then print this 2D vector and get these results as output.
\311[\240\3778\311[\240\377P\311[\240\377h\311[\240\377\200\311[\240\377\230\311[\240\377\260\311[\240\377\310\311[\240\377\340\311[\240\377\370\311[\240\377\312[\240\377(\312[\240\377#\312[\240\377X\312[\240\377p\312[\240\377\210\312[\240\377\240\312[\240\377\270\312[\240\377\320\312[\240\377\350\312[\240\377\313[\240\377\313[\240\3770\313[\240\377H\313[\240\377`\313[\240\377x\313[\240\377\220\313[\240\377\250\313[\240\377\300\313[\240\377\330\313[\240\377\360\313[\240\377\314[\240\377 \314[\240\3778\314[\240\377P\314[\240\377h\314[\240\3771110+2+,0,+a_0co0%We0Enab1AK1ages1eKey0r_1ons_1rvic0_000069631Ap1SUse1co0PKSe1NSLi1e_0"NSA0led_1tion1NSPr1DMSE0ging0mptD0ionE1sDat0appl1A_001D6961y_0mati0$NSA0able1nEna0sRequested_Microsoft Controller_#NSAutomaticQuoteSubstitutionEnabled\Dell S2830dn_AppleMiniaturizeOnDoubleClickQ1 \2410Uen-US3A\300\274\265\302\317+w\32134VdirMap\320 U10.14\241:\323;<=>?#WreplaceTwithRonSomwZOn my way!"?\2003A\300\321i\245z% XMaximizeUen_US\321GH_NSWebServicesProviderW,\200\306IJKL_qDisplayName_NSProviderIdentifierVGoogle^com.google.www 3A\300\321j
\273\375 3A\300\320Sa.$p\245RSTUV_0~/Desktop/CompSci 2100/2100Project3/2100Project3_ ~/Desktop/CompSci 2100/Project_2_~/Desktop/CompSci 2100_#~/Desktop/CompSci 2110/2210project2_0~/Desktop/CompSci 2110/2210Project3/2210Project3#?\340TDark \244]E^_RenRtrRfr _{\233\303\333\361 =_s\221\300\333\3709Y}\232\277\322\355\371*Hc\206\241\265\3223Z\201\244\306\335023457=FIPQRTZ\^emruy\204\206\213\224\225\236\244\247\310\315\344\373%+^\201\232\300\363\374 binput1.txt
\377\377\377\377\377q\205<оa\310\214 CPX#\360dCFPreferencesMessages\340#
\360\200CFPreferencesShmemName\220apple.cfprefs.501v1CFPreferencesShmemIndex0\364CFPreferencesShmemState#\360\200CFPreferencesShmemName\220apple.cfprefs.501v1CFPreferencesShmemIndex0\245CFPreferencesShmemState#\360\200CFPreferencesShmemName\220apple.cfprefs.501v1CFPreferencesShmemIndex0\343CFPreferencesShmemState#\360\200CFPreferencesShmemName\220apple.cfprefs.501v1CFPreferencesShmemIndex0YCFPreferencesShmemState#\360TCFPreferencesShmemName\220apple.cfprefs.501v1CFPreferencesPropertyList\200\255bplist00\337
234_com.apple.trackpad.version_.com.apple.trackpad.fourFingerHorizSwipeGesture_.com.apple.trackpad.fourFingerPinchSwipeGesture_.com.apple.trackpad.fiveFingerPinchSwipeGesture_com.apple.mouse.tapBehavior_ com.apple.trackpad.rotateGesture_com.apple.ColorSync.Devices_'com.apple.trackpad.enableSecondaryClick_com.apple.trackpad.pinchGesture_!com.apple.trackpad.scrollBehavior_5com.apple.trackpad.twoFingerFromRightEdgeSwipeGesture_)com.apple.trackpad.threeFingerDragGesture_(com.apple.trackpad.threeFingerTapGesture_/com.apple.trackpad.threeFingerHorizSwipeGesture_-com.apple.trackpad.fourFingerVertSwipeGesture_.com.apple.trackpad.threeFingerVertSwipeGesture_#PKSecureElementAvailableFlagsByHost_!com.apple.trackpad.momentumScroll_,com.apple.trackpad.twoFingerDoubleTapGesture \322+_0Device.cmra.63306330-3362-6536-3839-633063343435_0Device.mntr.C07EE717-D5E0-4933-131D-70E3DC02779B\322!_DeviceDescriptions_FactoryProfiles\321 Uen_USViPhone\322"#$*Y555810816_DeviceDefaultProfileID\322%&')_DeviceModeDescriptions_DeviceProfileURL\321(WDefault_[/System/Library/Frameworks/ICADevices.framework/Versions/A/Resources/Camera RGB Profile.iccY555810816\321,-^CustomProfiles\321./Q1_:/System/Library/ColorSync/Profiles/Generic RGB
it is actually a lot more than this but I think that would be too much for a question. It prints stuff like this sometimes only one sentence long sometimes forever. I have never experienced something like this I am just trying to print a 2D vector I have done this 1,000's of times with no problems. I am using xCode and here is my code for the whole project.
//read in the file into a double vector
#include <iostream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <sstream>
using namespace std;
class OBJs{
public:
string Obj;
int numItemsInObj;
};
//vector to store all of the data for the grid and the row of the big vector
vector<OBJs> row;
vector<vector<OBJs>> grid;
//maybe create an object for the found parameters
OBJs tempObj;
//functions
void load(string fileName);
void printObjs();
int main(int argc, const char * argv[]) {
string file;
cout << "Please enter your filename here: ";
cin >> file;
load(file);
printObjs();
return 0;
}
void load(string fileName){
//read in a line and insert the line(string) into the second index of the vector
string line;
string zeroOrOne;
ifstream file;
file.open(fileName);
//basically a guard let function in swift
if(!file){
cout << "Could not open the file " << fileName << endl;
//exit(0);
}
// you have successfully entered the file specified
while(getline(file, line)){
//grabbing each line of the file into the var line
//delimit this line by , in getline
istringstream ss(line);
while(getline(ss, zeroOrOne, ',')){
//put it into the row vector.
tempObj.Obj = zeroOrOne;
tempObj.numItemsInObj = 0;
row.push_back(tempObj);
}
//put the row in the grid.
grid.push_back(row);
}
file.close();
}
void printObjs(){
for(int i =0; i < grid.size(); i++){
for(int j =0; j< row.size(); j++){
if(grid[i][j].Obj == ""){
//cout << "nothing in this element" << endl;
} else {
cout << grid[i][j].Obj;
}
}
cout << endl;
}
}
In printObjs() you are limiting the loop index j with row.rize():
for(int j =0; j< row.size(); j++)
but use it to index into grid with grid[i][j].Obj. There is no reason that the size of row should be equal to that of grid[i]. Therefore you probably are accessing out-of-bounds causing undefined behavior.
It should probably be for(int j =0; j< grid[i].size(); j++) instead.
You also shouldn't be using global variables if it is not necessary. Both tmpObj and row are only used in load. Therefore declare them there.
Similarly grid can be a local variable, passed around between the functions.
There are couple of problems in your code. Firstly:
while (getline(file, line)) {
istringstream ss(line);
while (getline(ss, zeroOrOne, ',')) {
tempObj.Obj = zeroOrOne;
tempObj.numItemsInObj = 0;
row.push_back(tempObj);
}
grid.push_back(row);
}
Notice what's happening. You read every number per single line, add it to row and then add row to grid. What happens when you read the second line? You read more numbers and add more numbers to row. Now your row contains numbers from both first and second lines. You want to clear the row after copying it to the next element in the grid, like so:
while (getline(file, line)) {
istringstream ss(line);
while (getline(ss, zeroOrOne, ',')) {
tempObj.Obj = zeroOrOne;
tempObj.numItemsInObj = 0;
row.push_back(tempObj);
}
grid.push_back(row);
row.clear();
// ^ notice the clear() call here
}
There is also another issue. Here:
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < row.size(); j++) {
if (grid[i][j].Obj == "") {
//cout << "nothing in this vector" << endl;
} else {
cout << grid[i][j].Obj;
}
}
cout << endl;
}
you don't want to check for row.size(). You want to operate on the grid and you want the length of the ith row of the grid. Simply change it to:
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[i].size(); j++) {
// notice the change here ^^^
if (grid[i][j].Obj == "") {
//cout << "nothing in this vector" << endl;
} else {
cout << grid[i][j].Obj;
}
}
cout << endl;
}

Reading text file c++ (not able to display other lines)

char fname[20];
char lname[20];
int grade[10];
double avg=0.00;
fstream infile("C:\\Users\\Hady Zn\\Desktop\\hady.txt", ios::in);
fstream outfile("C:\\Users\\Hady Zn\\Desktop\\hady1.txt", ios::out);
while(infile>>fname>>lname)
{
outfile<<fname<<" "<<lname<<" ";
for(int i=0; i<10; i++)
grade[i]=0;
for(int i=0; i<10; i++)
{
infile>>grade[i];
if(grade[i]>=0 && grade[i]<=100)
{
outfile<<grade[i]<<" ";
avg+=grade[i];
}
}
outfile<<avg/10.00<<endl;
avg=0.00;
}
So the question is that i need to read from a text file a last name(space) first name(space) then 10 quiz grades(space between each grade) and write the same data into an output file with the average of 10 quizzes at each end of a line. The problem that im facing is that if i had less than 10 quizzes on one line it will not display the remaining lines.(I want it to still give me the average of the grades given considering for example if i was given 7 grades 3 will be zeros) I tried solving it but it just won't work. Any ideas that can solve this? Please help. Thank you
In order to perform such checks, it's better to read the text from the input file line by line and process each line to extract the data.
string line
while ( getline(infile, line) )
{
istringstream sstream(line);
sstream >> fname >> lname;
if (!sstream )
{
continue;
}
outfile<<fname<<" "<<lname<<" ";
for(int i=0; i<10; i++)
{
grade[i]=0;
sstream>>grade[i];
if ( !sstream )
{
break;
}
if(grade[i]>=0 && grade[i]<=100)
{
outfile<<grade[i]<<" ";
avg+=grade[i];
}
}
}
Update, in response to comment by OP:
You can avoid reading the input file line by line and processing each line. Here's my suggested changes to the loop.
while(infile>>fname>>lname)
{
outfile<<fname<<" "<<lname<<" ";
for(int i=0; i<10; i++)
{
grade[i]=0;
infile>>grade[i];
if ( !infile )
{
infile.clear();
break;
}
if(grade[i]>=0 && grade[i]<=100)
{
outfile<<grade[i]<<" ";
avg+=grade[i];
}
}
outfile<<avg/10.00<<endl;
avg=0.00;
}

Read file from txt

I ve got a txt file with double matrix 50x8. The first two lines contains the array size
50
8
the 50x8 matrix. When i trid to read this file with the above code:
#include<iostream>
#include<fstream>
using namespace std;
int main() {
ifstream infile;
infile.open("C:/Users/zenitis/Desktop/BTHAI_2.3b-src/BTHAI/txtFiles/W1.txt");
double events[50][8];
while (!infile.eof())
{
for(int j=0;j<50;j++)
{
for(int k=0; k<8;k++)
{
infile >> events[j][k];
// infile.get(c
}
}
} //end while
infile.close();
for(int i = 0; i<50; i++){
for(int l=0; l<8; l++){
cout << events[i][l] << " ";
}
cout << "\n";
}
cout << events[0][0];
system("pause");
return 0;
}
Firstly when i print the results the first two elements of the events matrix are the last two of the file. Secondly any idea how to read just the two first elements which is in fact the size of the matrix????
You read the number of rows and columns like this:
int R, C;
infile >> R;
infile >> C;
You do it before the nested loops that read the rest of the file. Then you use the numbers from the file as your end-of-loop targets, rather than hard-coding 50 and 8.

flush out buffer into file

int main()
{
string line;
char buff[10];
for(int i=0; i<10;i++)
{
cin.get(buff[i]);
cout.put(buff[i]);
if(i==10)
{
ofstream file;
file.open("TEXT",ios::out);
for (i=0 ; i<10 ;i++)
file << buff[i] << endl;
file.close();
}
}
}
this code is not flushing the data from array to file and even file is also not created...
No, because inside your loop, i<10, so your conditional is never executed. Put the flushing code after the loop.