I want to read a file with std::getline. but reads first line only
string FileReader::readLine() {
string line;
string read;
ifstream ReadFile;
ReadFile.open("input.txt");
if (ReadFile.is_open()) {
getline(ReadFile, line);
//ReadFile.close();
}
return line;
}
this is my method. I call this method several time but always reads first line how can i do to read next lines?
You need to change your program flow.
Don't return a string. Use the line within the loop to do whatever it is you want. Ensuring that you either don't leave the method or return to it.
You can't keep coming back to a function like this, as it will keep reading from the beginning.
void FileReader::readLine() {
string line;
string read;
ifstream ReadFile;
ReadFile.open("input.txt");
if (ReadFile.is_open()) {
while(getline(ReadFile, line))
{
//do what you want with that line, but return program flow here.
}
ReadFile.close();
}
}
Related
I am trying to use getline on a file (unkown size) to grap the first line, input it into a string, manipulate this string (replace words with others, move some around) and output the manipulated line back to the file.
After this, I need to do the same thing to line 2, 3, etc. until the end of the file. How would I go about doing this? I figured a while loop for getline would work, but not sure how to get the conditions for the while loop or how to manipulate each line individually. Such as lines 1 and 3 must be manipulated differently than lines 2 and 4. etc.
A rough idea of what I'm trying to do:
void readFile(string filename, string text)
{
ifstream infile;
infile.open(filename);
getline(cin, text) // pretty sure this is wrong..
infile.close(); // close here, or after manipulation???
}
void swapText(string filename, string text)
{
string decrypText;
//Manupulate several things..
return decrypText;
}
void writeToFile(string filename, string decrypText)
{
ofstream outfile;
outfile.open(filename);
outfile << decrypText << endl;
outfile.close();
}
The standard idiom for reading text lines from a file and storing them is:
std::vector<std::string> file_data;
std::string text_line;
while (std::getline(my_data_file, text_line))
{
// Optional: store the text line
file_data.push_back(text_line);
// Call a function to process (or ignore) the text line:
Process_Text_Line(text_line);
}
If you want to have a function that reads the file, you may need to pass the vector:
void Read_File(std::vector<std::string>& file_data)
{
//...
// Read the data, see "while" loop above.
}
Don't open and close the file for every read. Keep it open and read a line at a time:
std::istream in("filein.txt");
std::ostream out("fileout.txt");
std::string line;
while (std::getline(in, line)) {
// modify line as appropriate
out << line << '\n';
}
I'm trying to to read ~36KB and it would take ~20 seconds to finish this loop:
ifstream input_file;
input_file.open("text.txt");
if( !(input_file.is_open()) )
{
cout<<"File not found";
exit(1);
}
std::string line;
stringstream line_stream; //to use << operator to get words from lines
int lineNum=1;
while( getline(input_file,line) ) //Read file line by line until file ends
{
line_stream.clear(); //clear stream
line_stream << line; //read line
while(line_stream >> word) //Read the line word by word until the line ends
{
//insert word into a linked list...
}
lineNum++;
}
input_file.close();
Any help would be appreciated.
stringstream::clear() does not clear all context inside it. It only resets the error and EOF flags, see http://en.cppreference.com/w/cpp/io/basic_ios/clear.
The result is your line_stream accumulates all previous lines and the inner loop will run words over all the accumulated lines again and again.
So the total time you spend is about O(n^2) compared to O(n) of what you expect it to be.
Instead of using the same object across each line, you could define the new line_stream instance inside the while loop to have a brand new and also empty one. Like this:
fstream input_file;
input_file.open("text.txt");
if( !(input_file.is_open()) )
{
cout<<"File not found";
exit(1);
}
std::string line;
int lineNum=1;
while( getline(input_file,line) ) //Read file line by line until file ends
{
stringstream line_stream; // new instance, empty line.
line_stream << line; //read line
while(line_stream >> word) //Read the line word by word until the line ends
{
//insert word into a linked list...
}
lineNum++;
}
input_file.close();
You could attempt the following:
std::ifstream file("text.txt");
std::string str;
while (std::getline(file, str))
{
cout << str; //call function to to retrieve words of str in memory not in file
}
I ran your code in 11ms, but with the mentioned option in 8ms. May be it works for you.
Try compiling with build flag -O2 or -O3.
I was surprised to see that a simple for-loop to read a 1GB file took 4.7 seconds, whereas another higher level language (Dart) did it in 3.x seconds.
After enabling this flag, runtime dropped to 2.1 seconds.
I need help, I tried googling if I could find a similar problem but the solutions for others didn't work for me.
I'm trying to use getline() to read the file I've opened but it's not accepting the parameters I've given it.
What I'm trying to accomplish at this time (not the entire program) is to open a .csv file and determine how many elements it has inside by using getline() and using the , character as the delimiter. My loop has an index which I could just add 1 to it so that I can get the total number of elements inside the file.
The reason I'm doing this is because I intend to use it for a project at school but so far I've gotten stuck at the getline() error:
no matching function for call to 'std::basic_ifstream::getline(std::string&, int, const char [2])'
My code is here:
void readfile(string a)
{
int i = 0;
ifstream infile;
infile.open(a.c_str());
string temp;
//count how many elements are inside
if(infile.is_open())
{
while(infile.good())
{
infile.getline(temp, 256, ",");
i++;
}
infile.close();
i+=1;
}
else
{
cout<<"Error opening file.";
}
cout<<i;
}
Use the free getline() function:
std::string line;
getline(infile, line);
In addition to the answer by #UlrichEckhardt, I'd handle delimiters like this:
if(infile.is_open())
{
string temp;
// std::getline(std;:istream&, std::string) used below
while(getline(infile, temp)) {
std::stringstream stream(str);
std::string token;
while (std::getline(stream, token, ','))
if (!token.empty()) // it's up to you to decide how to handle empty tokens
i++;
}
}
Note the ','. If it were ".", this would be considered a string by the compiler, which is exactly what you're seeing in the error message: a '\0' is appended automatically, thus producing a char[2].
the fstream and string inlcusions are in the .h file. I've read multiple people's problems but can't seem to apply it to my own. I've tried putting in infile.getfile(dataFile, line)) to no avail. The dataFile is just a list of employees. I still keep getting the same no instance of overloaded function with getfile(dataFile, line)
{
ifstream infile;
infile.open(dataFile);
if(!infile.good())
{
cout << "File is not open";
}
else
{
int i = 0;
while(!infile.good())
{
string line;
while (getline(dataFile, line))
{
if (line[0] == 'h' )
{
HospitalEmployee newEmp;
}
}
}
}
}
while (getline(dataFile, line))
The first argument is the stream, and the second argument is the string where the line will be assigned. You got the second argument right, but the first argument is a string object, not the file stream from which the line will be extracted. You're supposed to pass the stream, inFile:
while (getline(inFile, line))
// ^^^^^^
Your infile.open(dataFile) suggests that dataFile is the string filename and infile is the stream.
So, instead of getline(dataFile, line), you mean getline(infile, line).
Typo, I'm sure.
How do I ignore an empty first line in "input.txt"? I don't necessarily know that there is an empty line (in this particular case there is, but I want to make my code generic), so I need to be able to read the line if there is information, or skip it if it is blank. This is just for the first line.
while (getline(mcFile, line)) {
istringstream liness2(line); ... }
That's how I'm reading the lines. If I knew for certain that any input file I ran this on had an empty first line, I would just do "getline" before, but I don't know that.
string data;
while (getline(inputFile, data))
{
if (data == "") continue; // Skip blank line
... // Do stuff with non-blank line
}
ifstream ReadFile;
ReadFile.open("input.txt");
string content;
string line;
if (myReadFile.is_open()) {
while (!ReadFile.eof()) {
getline(cin,line);
content += line + '\n';
if (!line.empty()) {
/// do what you want to do
}
}
}