Fill an array with getline loop - c++

Would like to fill an array one line at a time from the file "Hello.cpp". However if I do it the way below I fill the entire file [w] times instead of just grabbing one line from the file for each iteration of i.
If I remove the { } from getline then the array is filled with the last line of "Hello.cpp" [w] times.
I am not sure how to get a new [i] each time from the Hello.cpp file.
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main() {
int w=0;
ifstream in("Hello.cpp");
string s;
while(getline(in, s))
w=w+1; //first count the number of lines in the file for the array
string a[w];//make an array big enough for the file
for(int i = 0; i < w ; i++) {
ifstream in("Hello.cpp");
string s;
while(getline(in, s)){
a[i] = s;
cout << i + 1 << " " << s << endl;
}
}

I would close your file before reopening it (best practice).
Looks to me like you need to move your file open (ifstream constructor) outside of your for (do you really want to open the file w times)? Since you bother to count the lines first don't you really want something like this:
ifstream in1("Hello.cpp");
for(int i = 0; i < w ; i++) {
getline(in1, a[i]);
cout << i + 1 << " " << a[i] << endl;
}

Related

stock data from file into arrays c++

I have this specific code to read integers from a text file:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
bool contains_number(const string &c);
int main()
{
int from[50], to[50];
int count = 0;
{
string line1[50];
ifstream myfile("test.txt");
int a = 0;
if (!myfile)
{
cout << "Error opening output file" << endl;
}
while (!myfile.eof())
{
getline(myfile, line1[a]);
if (contains_number(line1[a]))
{
count += 1;
myfile >> from[a];
myfile >> to[a];
//cout << "from:" << from[a] << "\n";
//cout << "to:" << to[a] << "\n";
}
}
}
return 0;
}
bool contains_number(const string &c)
{
return (c.find_first_of("1:50") != string::npos);
}
I need to stock these values of from[] and to[] in 2 arrays to use them n another function, I tried to create 2 arrays in a simple way and affect the values for example:
int x[], y[];
myfile >> from[a];
for(int i=0; i<50;i++)
{
x[i] = from[i];
}
but it doesn't work. It seems that this way is only to read and display and a value in from will be deleted once another value comes.
Any help?
Thanks.
You're not incrementing your array index a in your loop. This results in line[0], to[0] and from[0] to be overwritten for every line in the file where contains_number returns true.
There is no reason for you to save your lines into memory. You can just process your lines as you go through the file (i.e. create a string line variable in your while loop).
Make sure you properly close your file handle.
Aside from that you should check your index bounds in the loop (a < 50), else you might be writing out of bounds of your arrays if your file has more numbers than 50.
A better solution yet would be to use vectors instead of arrays, especially if your file may contain any number of numbers.

Read a .dat File and create an array C++

I try to read a .dat file with a list of coordinates X and Y. My code work to count the lines in the file but it doesn't work to read the coordinates correctly. In the output just show me the number of lines in the .dat file, but it doesn't show me the coordinates. .dat file has 2 column and more than 5 rows (I have many files with different amount of coordinates). Any help is super welcome, i am very new in C++.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main() {
std::vector<int> numbers;
ifstream fileB;
const int SIZE=10;
char filas_dat [SIZE];
fileB.open("Verticesfixed_cell1slc44.dat");
std::string line;
int counter=0;
while (getline(fileB, line)) //contador de filas
{
++counter;
}
if(!fileB.good())
{
int current_number = 0;
while (fileB >> current_number){
numbers.push_back(current_number);}
fileB.close();
cout << "The numbers are: ";
for (int count = 0; count < numbers.size(); count++){
cout << numbers[count] << " ";}
cout << endl;
}
else
{
cout << "Error!";
}
return 0
}
The problem is that after you've counted the number of lines you are at the end of the file, so there is nothing more to read. A file doesn't reposition itself back to the beginning automatically. You have to tell the file to go back to the beginning.
A second similar problem is that when you get to the end of your file the getline function fails (because there's nothing more to read). That puts your file into an error state when nothing will work until you clear the error state.
Finally the call to !fileB.good() is unecessary. The file will never be good at this point, again this is because getline has failed.
Try this code
while (getline(fileB, line)) //contador de filas
{
++counter;
}
fileB.clear(); // clear the error state
fileB.seekg(0); // go back to the beginning of the file
int current_number = 0;
while (fileB >> current_number)
{
numbers.push_back(current_number);
}

Read csv file using 2d array

I'm trying to read a CSV file using 2d array but there's a problem with the reading. The first cell of the file is skipped and then continues read all. I don't understand why it doesn't read the first cell.
#include<iostream>
#include<fstream>
#include<cstring>
#include<string>
#include<sstream>
using namespace std;
int main()
{
string arrival,job[3][4];
ifstream jobfile("myfile.csv");
std::string fileCommand;
if(jobfile.is_open())
{
cout << "Successfully open file"<<endl;
while(getline(jobfile,arrival,','))
{
for(int i=1;i < 4;i++) //i = no. of job
{
for(int j=0; j<4; j++) // j = no. of processes
{
getline(jobfile,job[i][j],',');
cout << "Job[" << i << "]P[" << j << "]: "<< job[i][j]<< endl;
}
}//end for
}//end while
}//end if for jobfile open
jobfile.close();
}
Change this:
for(int i=1;i < 3;i++)
to this:
for(int i=0;i < 3;i++)
Also, remove this getline(jobfile,job[i][j],',');, since you skip a line that way. When you called getline in the condition of the while loop, it already read a line (as a result, now, you have to store that line. Then, when the condition of the while loop is evaluated again, the next line will be read).
However, it gets much more complicated than this, since you arrival will hold one token at a time, until it meets the last token of the current line. In that case, arrival will be this: "currentLineLastToken\nnextLineFirstToken".
For that reason, you need to specially handle the case that arrival contains a newline, use string::find for this.
When a newline is found, you should split that string to that newline, in order to extract the two tokens involved. Use string::substr for this.
Moreover, you shouldn't loop inside the while loop with a double for to store the token, you just read. Use a double for loop, when it is time to print job, only after exiting the while loop that read the file.
Putting everything together, we get this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string arrival,job[3][4];
ifstream jobfile("myfile.csv");
std::string fileCommand;
if(jobfile.is_open())
{
cout << "Successfully open file"<<endl;
int i = 0, j = 0;
while(getline(jobfile,arrival,','))
{
//cout << "|" << arrival << "|" << endl;
size_t found = arrival.find("\n");
if (found != std::string::npos) // if newline was found
{
string lastToken = arrival.substr(0, found);
string nextLineFirstTOken = arrival.substr(found + 1);
job[i++][j] = lastToken;
j = 0;
if(nextLineFirstTOken != "\n") // when you read the last token of the last line
job[i][j++] = nextLineFirstTOken;
}
else
{
job[i][j++] = arrival;
}
}//end while
for(int i = 0; i < 3; ++i)
{
for(int j = 0; j < 4; ++j)
{
cout << job[i][j] << " ";
}
cout << endl;
}
}//end if for jobfile open
jobfile.close();
}
Output (for my custom input):
Successfully open file
aa bb cc dd
bla blu blo ble
qq ww ee rr

Reading a text file into a vector from the command line

Whenever I try to see the contents inside the vector I get "segmentation fault" any idea why that is? Do I not read in the values properly?
#include <iostream>
#include <cstdlib> // atoi function
#include <vector>
#include <fstream>
using namespace std;
vector<int> list ; // global vector
int main (int args , char * argv[])
{
ifstream in(argv[1]);
//ofstream out(argv[2]);
int listSize = atoi (argv[2]);
cout << listSize << endl;
int i = 0;
cout << argv[1] << endl;
in.open(argv[1]);
while (i < listSize)
{
in >> list[i];
cout << "test2" << endl;
i++;
}
in.close();
for( int k=0; k <listSize; k++){
cout<< list[k] << endl;
}
return 0;
}
the text file contains these numbers:
5 6 7 11 12 13
A vector doesn't automatically come with slots. You have to either reserve slots or use push_backto append items to the vector:
//...
int value;
in >> value;
list.push_back(value);
Read what's in the file using getline. See sample code below:
ifstream InFile(argv[1], ios::in); /*Open file from arg[1]*/
std::string LineContent;
getline(InFile, LineContent); /*Save line per line */
With your line saved in a string, you can now transfer the data from that string to the vector, see:
vector<int> list;
list.push_back(atoi(LineContent.c_str()));
Now, you can print out what's in the file:
for (int i = 0; i < list.size(); i++)
cout << list[i] << endl;

Why is my vector printing as blanks when values have been entered through a file?

I am trying to store strings from a file into a vector containing an array. The following is my way of getting information into the vector:
{
string line;
int nooflines = 0;
ifstream myFile("SongListFile.txt");
while (getline(myFile, line)) {
nooflines++;
}
song temp;
myFile.open("SongListFile.txt");
for (int i = 0; i < nooflines; i++) {
myFile >> temp.title;
myFile >> temp.artist;
myFile >> temp.genre;
songs.push_back(temp);
}
myFile.close();
}
And this is how im trying to print this information:
void SongList::ViewSongList() {
int last_element_position = songs.size() - 1;
for (int i = last_element_position; i >= 0; i--)
{
cout << "\"" << songs[i].title << "\" by " << songs[i].artist << " (" << songs[i].genre << ")" << endl;
}
Why are the strings printing as if they contain nothing? Two of the templates print when there are two lines of text, so my problem is the strings not being stored in my array.
}
Apart that you could do the reading in one pass, as indicated in comments and other answers, the way you are "re-opening" the file is not correct. After the first pass a flag of your ifstream has been set when reaching the end of the file. Opening again the file (without closing) wont clear the flag.
You need either to myFile.close() before re-opening, or alternatively clear the flags then seek to the beginning:
myFile.clear(); // clear the flags
myFile.seekg(0, ios::beg); // seek back to beginning for the second pass
You don't need to count the number of lines in the file at all. You can do it in one pass :
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct Song { string title, artist, genre; };
int main() {
ifstream myFile;
myFile.open("songList.txt");
string aLine;
vector<Song> songs;
while(getline(myFile, aLine)) {
stringstream sin(aLine);
Song aSong;
sin >> aSong.title >> aSong.artist >> aSong.genre;
songs.push_back(aSong);
}
for(int i = 0; i < songs.size(); i++)
cout << "\"" << songs[i].title << "\" by " << songs[i].artist << " ("
<< songs[i].genre << ")" << endl;
return 0;
}