Cout empty when there are two getline? - c++

I am trying to cout my array but it keep showing empty whenever I try to.
int array_size = 0;
int pos;
string line;
ifstream inFile;
string filename = 'test.txt';
inFile.open(filename);
for(array_size = 0; getline(inFile, line); array_length++);
string * array_holder = new string[array_size];
while(getline(inFile, line))
{
array_holder[pos++] = line;
}
printArray(array_holder, array_size);
Print array
void printArray(string * data, int x)
{
for(int z = 0; z < x; z++)
cout << data[z] << endl;
}
When I comment out this line:
for(array_size = 0; getline(inFile, line); array_length++);
The printArray will show all the contents inside.
But when I uncomment the line, it just show empty lines (depending on the array size).
I reckon this is due to double getline? Do I need to clear the getline buffer or something? I couldn't find any details about getline buffer except for cin. Or is this memory issue?
Note that I cannot use vector in my situation and I need to read the total number of lines in the text file in order to parse the array size to my array syntax.
Thanks.

for(array_size = 0; getline(inFile, line); array_length++);
This loop reads inFile, one line at a time, until the end of the file is reached.
After this loop terminates, the entire file has been read. After all, that's exactly what your program tells your computer to do: read one line at a time, incrementing the counter, until getline fails, which happens at the end of the file. But then immediately afterwards, the second loop attempts to continue reading from the file:
while(getline(inFile, line))
However, since the end of the file has already been reached, this immediately fails, and nothing happens.
You obviously want to reread the file from the beginning, here. However, the Golden Rule Of Computer Programming states "your computer will always do exactly what you tell it to do, instead of what you want it to do". You have not told your computer to go back to the beginning of the file here, so it has no reason to do that. So, you simply have to tell your computer to do that, by closing and reopening the file, or by using the seekg() method.

Related

C++ reading file into multiple arrays

I am trying to read a file in from a text document into 2 arrays. I've ruled out the problem being in my other functions or my mains, and that leave about 5 lines of code....
It will cycle through my document to the end, but it only inputs the txt once through the loop. Any thoughts would be great!
void load_donations(string donor[], string donation[])
{
string text;
cout << "What *.txt file would you like to load? ";
cin >> text;
text += ".txt";
cout << text << endl;
ifstream infile;
infile.open (text.c_str());
int i = 0; //moves to next slot in array
while (!infile.eof())
{
getline(infile, donor[i]);
getline(infile, donation[i]);
i++;
}
infile.close();
}
The problem was that I wasn't passing my count from this function to the function that printed out my array.. I only noticed it when I went to create a minimal like Peter suggested. Feel free to kick me on my way out.
For this, you need to declare dynamic array of chars, and
Then read from file character by character and save that characters in dynamic array inside the loop.
Does this make sense to you ?

(C++) How to continue to read to the next line of a file, and yet stop at the end of a file?

I'm struggling to find a way to both read a file to the end of a line, such as
dog \n
cat \n
pig
and store the char of each to an array. While I can do this for one line, I can't work out how to move on to the next line (ie dog to cat) and still register the end of the file.
Here is my code so far;
searchFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
char next;
while (searchFile.get(next))
{
if (next == '\n') // If the file has been opened in
{
for (int i = 0; i <= searchTempSize; i++) // ... For each character within the total length of the string ...
{
searchCharArray[i] = searchArray[i];
cout << searchCharArray[i] << endl;
}
}
}
Edit for clarity: I need to read the file and store the characters of each word as an array. However, the file contains each word on a new line. I can't seem to find a way to read on to the next line, rather than end.
The conventional way to do this is with std::getline. This returns a reference to the stream; when casted to a boolean, this indicates whether the last operation on the stream was successful, e.g., non–end-of-file. So to load all lines into an array of strings, for example, you might do the following:
std::string line;
std::vector<string> lines;
while (std::getline(searchFile, line)) {
lines.push_back(line);
}

could'nt read correct values of vector produced from file

I am trying to read text file line by line and then read each column as vector but when i am tryin to cout first column it shows zeros i.e. not reading the file correctly.
int main(void)
{
ifstream myfile ("data1.txt");
string line;
if (myfile.is_open())
{
int ln=1;
while ( getline (myfile,line) )
{
if(ln==1){ln++; continue;}
istringstream iss(line);
string word;
vector<double> column;
int w=1;
while(iss >> word)
{
//double dw=atof(Form("%s",word));
column.push_back(atof(Form("%s",word)));
cout<<column[0];
w++;
}
ln++;
cout<<"\n";
}
myfile.close();
}
//else
else cout<<"Unable to open file";
cout<<"\n";
return ;
}enter code here
push_back appends an element as last element of the vector while columns[0] always refers to the first element of the vector.
Is the first element 0
Is there another problem?
(Please explain what is Form, give an example of input file and output in the command line)
First of all learn how to indent and consistently use some scheme for inserting blank lines that makes sense. When you do that you can read your own code and figure out if it is doing what you think it is.
Second. Save Form("%s",word) in a string ( for now call it form_string) add this line cout<<"form returns "<<form_string<<endl; 99.99% probably it will print zeros.
Finally change: cout<<column[0]; to cout<<column[0]<<" "; or cout<<*(column.rbegin())<<" ";. The latter prints out all the values that you read, the former prints out the first value you read over and over.

how to detect end of file for string inputs in C++

//Stores the line
string line;
//create a vector where each element will be a new line
vector<string> v;
int counter = 0;
//While we havent reached the end of line
while (getline(cin, line) && !cin.eof())
{
//get the line and push it to a vector
v.push_back(line);
counter++;
for(int i = 0; i <counter; i++)
{
cout<<v[i]<<endl;
}
}
return 0;
}
The problem is, how come if i input lets say:
Hello
World (end of file)
The output is only:
Hello
The World is not outputted it only outputs both Hello and World if I input
Hello
World
(end of file)
Sorry if this is a really simple question :/ but i can't figure this out
If you have a line that ends with EOF without end of line, this:
while (getline(cin, line) && !cin.eof())
will have a getline that returns "all ok", but since the getline got to the actual end of file, cin.eof() is also true, meaning that your loop will not process the LAST of your input.
Change the code so that it simply does:
while (getline(cin, line))
and all will be fine.
If you really care that you actually read the whole file, and getline didn't fail for some arbitrary other reason, then using something like this AFTER the loop may ensure that - but I find it rather hard to think of a case where this would happen...
if (!cin.eof())
{
cout << "Enexpected: didn't reach end of file" << endl;
}

Why using while(!input.eof()) loop twice not working? [duplicate]

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 9 years ago.
On the following lines of code is intended to put every words in the input text file(words are separated by new lines) to a vector of strings, then to turn each word inside out, and to see if this turned word is contained in the list of words in the input file.
I believe my binary search function and wordTurn function works fine.
I did several simple tests on my code, and I found out using while(!myFile.eof()) loop twice might be the cause for my code not working. By not working I mean I get the output file("pairs.txt") as an empty document(it is supposed to be a list of pairs of words).
That is, when I put some simple print code in the second while(!myFile.eof()) loop body, it did not get printed out, from which I concluded this loop is not reached. This is more likely, since it printed when I commented out the first while(!myFile.eof()) loop. I originally placed the first while loop at the else body, but this made no difference.
What do you think is the problem?
I tried combining those two loop body into the second loop, and it produces something in the output file, but this was not what this code was supposed to do, and this was logically not correct.
Any words of advice would be greatly appreciated.
int main(int argc, char* argv[]) {
vector<string> words;
ifstream myFile(argv[1]);
ofstream outputFile("pairs.txt");
string vocab;
string s;
int count;
while(!myFile.eof()) { //first while(!myFile.eof()) loop
getline(myFile, s);
words.push_back(s);
}
if(argc != 2) {
cout << "Usage: provide the name of one input file after the dictlookupHN executable file." << endl;
return (1);
}
else {
if(!myFile.is_open()) {
cerr << "Error: unable to open file " << argv[1] << endl;
return (1);
}
else {
while(!myFile.eof()) { //second while(!myFile.eof()) loop
getline(myFile, vocab);
string turnedWord = wordTurn(vocab);
if(binsearch(words, turnedWord) != "") {
outputFile << vocab << ":" << turnedWord << endl;
count++;
}
}
}
}
myFile.close();
outputFile.close();
return 0;
}
The ifstream class maintains an internal offset into the stream data, keeping track where it has to read from, for the next operation.
When this offset reaches the end, it stops the first loop, (eof() returns false). You need to reset this internal position back to the beginning of the file, before reading again.
You do that by saying:
myFile.clear(); // clear stream flags and error state
myFile.seekg(0, ios::beg); // reset read position
before the second loop.
Edit: Added call to clear().
What is happening is that the seek pointer for the file is at the end of the file when you complete the first run through the file. If you want to seek through the file again, you will need to reset the file pointer using myFile.seekg(0, ios::beg); before the second while loop. Something like this:
...
else {
myFile.seekg(0, ios::beg);
while(!myFile.eof()) { //second while(!myFile.eof()) loop
...
That should fix the problem.
If you want to read the file again [once you have read the entire file to the end] you will need to reset the bad/fail bits, and also seek to the start. End of file is a permanent state unless something is done to reset it.
So, you need myFile.clear(); and myFile.seekg(0, ios_base::beg);
Although I have a feeling you actually want to open a different file in this particular case, in which case, I would recommend closing the current one, and using a different variable - they aren't very expensive, and it makes the code clearer [particularly if you call it something sensible, e.g. vocabFile instead of myFile]
To read from the beginning of your file again, use:
myFile.seekg(0, ios::beg);
But note, that this is not a good way of reading from a file:
string vocab;
while(!myFile.eof()) {
getline(myFile, vocab);
...
}
This is how it should look like:
string vocab;
while(getline(myFile, vocab)) {
if (vocab.empty())
continue; // empty line might be read
...
}
Have a look at: Why does my input seem to process past the end of file?
The first loop reaches the end of file, and you're not resetting before the second read. You need to seek to the start of the file after the first loop: myFile.seekg (0, ios::beg); will do this for you.
the first loop reached EOF, thats the position of "read marker", so the second EOF is readed as first in the second loop.
As simple, try to close and open file between loop.
Better idea is to use seekg to read from top again.
Thank you everyone for all of these words of good advice.
They really helped me understand how the ifstream and eof work.
My TA's advice was to use for loop instead of the second while(!myFile.eof()) loop. I might be using this option, but your answers will be of great help when I have to use eof twice.
Thank you!
while(!myFile.eof()) {
string s;
getline(myFile, s);
words.push_back(s);
}
for(int i=0; i<words.size(); i++) {
//LOOP INV:
string vocab = words.at(i);
string turnedWord = wordTurn(vocab);
if(binsearch(words, turnedWord) == 1 && turnedWord.length() > 3) {
outputFile << vocab << ":" << turnedWord << endl;
count++;
}