The file that is being used as input is a .txt file that contains:
Line 1
Line 2
Line 3
Line 4
Line 5
And it is being opened on the 3rd line of my code. Yet the while loop never terminates, continuously print "Pass" to the console, so why is it not finding infile.eof() after the 5th line of text?
int main(int argc, char** argv) {
ifstream infile;
infile.open("TEST.txt", ios::in);
if(infile.is_open()){
while(!infile.eof()){
cout << "Pass" << '\n';
}
}
else{
cout <<"Fail";
}
}
Because you never actually consume (read) anything from infile to advance the file pointer. The code just continually checks for EOF, but doesn't actually read any contents of the file.
As others have pointed out, you don't do anything infile which causes an infinite loop. As to your question of how to do this right, try this:
int main()
{
ifstream infile("TEST.txt", ios::in);
string input;
while(infile)
{
getline(infile, input);
<do something with "input">
}
return 0;
}
Related
I am trying to write a program where I read a text file and then take each line in the textfile and store them in a string vector. I think I am able to open the textfile however I noticed that after I open the textfile anything after that point does not execute. For example I have a cout statement at the end of my main function that outputs when I enter the name of a file that doesn't exist. However if I type in a file name does exists I get no output from the last cout statement. Anyone know why this is? Thanks!
int main()
{
vector<string>line;
string fileName = "test.txt";
ifstream myFile(fileName.c_str());
int i = 0;
int count = 0;
vector<string>lines;
cout << "test" << endl;
if (myFile.is_open())
{
cout << "test2" << endl;
while (!myFile.eof())
{
getline(myFile, lines[i],'\n');
i++;
}
myFile.close();
}
if (!myFile.is_open())
{
cout<< "File not open"<< endl;
}
myFile.close();
cout << "Test3" <<endl;
return 0;
}
Try this:
string fileName = "test.txt";
ifstream myFile(fileName); // .c_str() not needed - ifstream can take an actual string
vector<string> lines;
string line; // temporary variable for std::getline
while (getline(myFile, line)) {
lines.push_back(line); // use push_back to add new elements to the vector
}
As pointed out in the comments, the most likely reason that your program seems to "end" prematurely is that it's crashing. std::getline takes a reference-to-string as its second argument. In your code, your vector is empty; therefore lines[i] for any i returns a reference to invalid memory. When getline tries to access that memory, the program crashes.
If you want an exception thrown when you try to access an out-of-bounds index of a vector, use lines.at(i) instead of lines[i].
You need to use push_back() because your initial vector is empty and, you can not use indexes on empty vector. If you do so, it will leads to undefined behavior.
std::ifstream input( "filename.ext" );
std::vector<std::string> lines;
for( std::string line; getline( input, line ); )
{
lines.push_back(line);
}
I tried making a program earlier that tells the user then number of char, words, and lines in a text file. I made functions to determine the numbers of each, yet I was passing them by value. This resulted in an error since after reading the number of char it would be at the end of the file and then output zero for the other two. Now I cant seem to rewrite my functions so that the file is open and closed each time its checked for char, words, and lines. Any one see where my errors are?? Thanks! (just copied and pasted one of my functions for now).
int num_of_lines(ifstream file)
{
string myfile;
myfile = argv[1];
ifstream l;
l.open(myfile);
int cnt3 = 0;
string str;
while(getline(file, str))cnt3++;
l.close();
return(cnt3);
}
int main(int argc, char **argv)
{
int num_of_char(ifstream file);
string file;
file = argv[1];
if(argc == 1)die("usage: mywc your_file");
ifstream ifs;
ifs.open(file);
if(ifs.is_open())
{
int a, b, c;
a = num_of_lines(ifs);
cout <<"Lines: " << a << endl;
}
else
{
cerr <<"Could not open: " << file << endl;
exit(1);
}
ifs.close();
return(0);
}
There is no way to "reopen" a file other than knowing the name and creating a new ifstream, but you can use the seekg member function to set your read position in the file, and setting it to 0 will have the next read operation start from the beginning of the file.
A stream is not possible to copy, so you can't pass it "by value", but must pass it by reference.
int num_of_lines(ifstream &file)
{
int count = 0;
string str;
while (getline(file, str)) {
count++;
}
file.seekg(0);
return count;
}
For the full problem, I agree with Mats Petersson, though. Counting both characters, lines and words in one pass will be much more efficient than reading through the file three times.
I am working on a program that should read from a file and store the contents of that file in a vector. I must read the contents of the .txt file and push the strings back into a vector before it reaches a ' '. If it is a space you will skip that part of the file and continue pushing back the contents after the space. Does anybody know what function to use to read from a file and put the contents into a vector or array? Thanks for your time.
int main()
{
Code mess;
ifstream inFile;
inFile.open("message1.txt");
if (inFile.fail()) {
cerr << "Could not find file" << endl;
}
vector<string> code;
string S;
while (inFile.good()) {
code.push_back(S);
}
cout << mess.decode(code) << endl;
return 0;
}
Basically you can also do it like this :
std::ifstream fh("text.txt");
std::vector<std::string> vs;
std::string s;
while(fh>>s){
vs.push_back(s);
}
for(int i=0; i<vs.size(); i++){
std::cout<<vs[i]<<std::endl;
}
You should change your reading code to
while (inFile >> S) {
code.push_back(S);
}
Your current code doesn't read anything into your S variable.
Regarding loop conditions while (inFile.good()) see this Q&A please:
Why is iostream::eof inside a loop condition considered wrong?
Using std::iostream::good() has more or less the same issues.
Good day, everyone
I would like to insert a dot (or any other char), after specified amount chars read (in my case it's 2)
So here is my code:
#include <fstream>
#include <string>
using namespace std;
string dot = "."; //Char to insert
char ch;
unsigned i=0; //Symbol counter
int counter = 2; //How much letters to skip before insertion
int main(){
fstream fin("file.txt", fstream::in);
while (fin >> noskipws >> ch) {
ofstream file;
file.open ("file2.txt");
file << ch;
file.close();
i++;
if(i == counter){
file.open ("file2.txt");
file << dot;
file.close();
i = 0;
}
}
return 0;
}
What i have written in my new file2.txt is "0".
P.S. I'm quite new in C++ so please explain in depth as for newbie (if you have time)
Thank you in advance.
EDIT: After applying few fixes output is now "."
EDIT2: It doesn't allow me to answer to my self post (because I'm newbie in this forum and have to wait 7h before answering), I'm going to post my fixed code here
Fixed version:
#include <fstream>
#include <string>
using namespace std;
string dot = "."; //Char to insert
char ch;
unsigned i = 0; //Symbol counter
int counter = 2; //How much letters to skip before insertion
int main(){
ofstream file;
file.open ("file2.txt");
fstream fin("file.txt", fstream::in);
while (fin >> noskipws >> ch) {
file << ch;
i++;
if(i == counter){
file << dot;
i = 0;
}
}
file.close();
fin.close();
return 0;
}
Thank you everyone for replies.
For a simple application like this, open the output file before you start reading, and don't close it until you're done. As written, the output file gets opened every time a character is read and then overwrites whatever was in the file before. You could open the file in append mode to stick new data on the end, but it's much simpler (and faster) to just keep it open.
Each time you write something to your output file, you open it, write your output, then close it. Because of the way you are opening your file, each of your writes start at the beginning of the file.
If instead, you leave your output file open until you are finished writing all your data, then next write will continue at the point the previous write ended, producing the sequence of output you are expecting.
ofstream file;
file.open("file2.txt");
while (fin >> noskipws >> ch) {
file << ch;
i++;
if (i == counter) {
file << dot;
i = 0;
}
}
Just open file in beginning , updated it and finally close all files.
ofstream file; <------------+
file.open ("file2.txt"); |
|
while (fin >> noskipws >> ch) { |
|
//ofstream file; ---+ |
+----->------+
//file.open ("file2.txt"); ---+
file << ch;
//file.close();
i++;
if(i == counter){
//file.open ("file2.txt");
file << dot;
//file.close();
i=0;
}
}
//Close files
file.close();
fin.close() ;
When you write to a file in a loop, you most likely want to to open the file outside of the loop. Normally when you open a file for writing, the old content will be overwritten.
So do this:
ofstream file ("file2.txt")
while (...)
{
...
file << ....
...
}
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[])
{
ifstream is;
is.open(argv[1]);
ofstream outfile;
outfile.open(argv[2]);
char ch;
while (1)
{
ch = is.get(); // this is where test.txt is supposed
outfile.put(ch); // to be copied to test2.txt
if (is.eof())
break;
cout << ch; //this shows
}
is.close();
outfile.close();
ifstream outfile2;
outfile2.open(argv[2]);
char ch2;
while (1)
{
ch2 = outfile2.get();
if (outfile2.eof())
break;
cout << ch2; //this doesnt
}
outfile2.close();
system("PAUSE");
return 0;
}
I run it through cmd giving it 2 arguments test.txt test2.txt and it outputs what i have written in test.txt in cmd but test2.txt remains empty for some reason?
Please check the streamstate not just for eof() but also for failure. Also, after reading the last character, it wouldn't be uncommon if the streamstate was EOF even though the character was successfully read. Therefore, always try to read an element and if it succeeded, and only then, use the element:
ifstream in(argv[1]);
ofstream out(argv[2]);
char c;
while(in.get(c))
out.put(c);
To make this really efficient, use this though:
out << in.rdbuf();
In any case, check the streamstate for success:
if(!in.eof())
throw std::runtime_error("failed to read input file");
if(!out.flush())
throw std::runtime_error("failed to write output file");
for me its not coming blank but with some extra appended characters. this is because you are writing the character which you got from the old file to the new one before checking eof().
the code for writing from one file to another should be changed as
while (1)
{
ch = is.get();
if (is.eof())
break;
outfile.put(ch);
cout << ch; //this shows
}