Issue with reading file content - c++

I have a file which contains text. I read line by line of the entire file and append to a string object. But when i get the final string print out i am not getting the whole file content. I am sure it is due to the presence of special characters like '\n', '\r', '\t', etc.
here is my sample code:
// Read lines until end of file (null) is reached
do
{
line = "";
inputStream->read_line(line);
cout<<"\n "<<line;//here i get the content of each line
fileContent.append(line);// here i am appending
}while(line.compare("") != 0);

This is the way to read a file into memory in C++:
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;
int main() {
vector <string> lines;
ifstream ifs( "myfile.txt" );
string line;
while( getline( ifs, line ) ) {
lines.push_back( line );
}
// do something with lines
}

You’ll have to show more code for me to know what your problem is.
If you’re reading the entire file into a single string, this is the method I usually use:
#include <string>
#include <fstream>
#include <iterator>
std::string read_file(const char *file_name)
{
std::filebuf fb;
if(!fb.open(file_name, std::ios_base::in))
{
// error.
}
return std::string(
std::istreambuf_iterator<char>(&fb),
std::istreambuf_iterator<char>());
}

Related

C++ - work with file (read file) then show in the console

I would like to read the content from the text file by C++ , I wrote the code as below:
#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <fstream>
using namespace std;
int main(int argc, char const *argv[])
{
ifstream input("C:\\Users\\thang\\Desktop\\Thang\\output.txt");
string str;
while(!input.eof()) //check if it goes to the end of the file
{
//getline(input,str); //
input>>str; // get the value of str from the file
cout<<str<<endl;
}
return 0;
}
But it just show me the result with no empty row , but the output.txt file has the empty line.
I have attached the screenshot
Could you please help explain why it get the result without the empty line ? Appriciated for all assist.
Because the operator>> to read std::string from std::ifstream skips leading whitespaces. Newline characters is one kind of whitespace characters, so they are ignored.
Because input>>str strips away any leading whitespace.
If you just need to read the file like cat does, use rdbuf directly:
ifstream input(...);
std::cout<<input.rdbuf()<<std::endl;
If you want to iterate over the lines, including the empty ones, use std::getline
ifstream input(...);
for (std::string line; std::getline(input, line); )
{
...
}

Trouble with parsing text file based on commas (C++)

I am working on creating a program that is supposed to read a text file (ex. dog, buddy,,125,,,cat,,,etc...) line by line and parse it based on commas. This is what I have so far but when I run it, nothing happens. I am not entirely sure what i'm doing wrong and I am fairly new to the higher level concepts.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <cstdlib>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
std::ifstream file_("file.txt"); //open file
std::string line_; //declare line_ as a string
std::stringstream ss(line_); //using line as stringstream
vector<string> result; //declaring vector result
while (file_.is_open() && ss.good())
{ //while the file is open and stringstream is good
std::string substr; //declares substr as a string
getline( ss, substr, ',' ); //getting the stringstream line_ and substr and parsing
result.push_back(substr);
}
return 0;
}
Did you forget to add a line like std::getline(file_, line_);? file_ was not read from at all and line_ was put into ss right after it was declared when it was empty.
I'm not sure why you checked if file_ is open in your loop condition since it will always be open unless you close it.
As far as I know, using good() as a loop condition is not a good idea. The flags will only be set the first time an attempt is made to read past the end of the file (it won't be set if you read to exactly the end of the file when hitting the delimiter), so if there was a comma at the end of the file the loop will run one extra time. Instead, you should somehow put the flag check after the extraction and before you use the result of the extraction. A simple way is to just use the getline() call as your loop condition since the function returns the stream itself, which when cast into a bool is equivalent to !ss.fail(). That way, the loop will not execute if the end of the file is reached without extracting any characters.
By the way, comments like //declaring vector result is pretty much useless since it gives no useful information that you can't easily see from the code.
My code:
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
int main()
{
std::ifstream file("input.txt");
std::string line, word;
std::vector<std::vector<string>> result; //result[i][j] = the jth word in the input of the ith line
while(std::getline(file, line))
{
std::stringstream ss(line);
result.emplace_back();
while(std::getline(ss, word, ','))
{
result.back().push_back(word);
}
}
//printing results
for(auto &i : result)
{
for(auto &j : i)
{
std::cout << j << ' ';
}
std::cout << '\n';
}
}

How to ignore line breaks in file handling

Is there any way to skip line breaks while reading a text file?
For example, lets say I have two text files, input.text and output.text.
My input.text file look like this:
welcome to stackoverflow<line break here>
another sentence
.
.
.
I read the first line from input.text and write some part of the line to output.text.
But when I read the second line after the line break, my first line gets lost in the text file.
What should I do?
To read the file I use this code:
ifstream input.open("input.text");
while(input)
{
getline(input,string);
}
and to write
ofstream output;
output<<string;`
Your problem has nothing to do with the enter key and everything to do with how you are reading/writing from the file. Your code apparently looks like this:
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string string;
std::ifstream input("input.text");
while (input) { // bad
std::getline(input, string);
}
std::ofstream output("output.text");
output << string;
}
The "while" loop overwrites string for each line. If you had 3 lines of text, at the end of the while loop, string would contain only the last line of the input file.
What you perhaps want to do is something more like:
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string string;
std::ifstream input("input.text");
std::ofstream output("output.text");
while (std::getline(input, string)) {
output << string;
}
}
Here is a simpler version using cin and cout:
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string string;
while (std::getline(std::cin, string)) {
std::cout << string;
}
}
As written, the "\n" at the end of each line goes missing: http://ideone.com/0FhEyj you can fix this by changing the output line to be
std::cout << string << "\n";

How to read line by line and override a line in the same file

I read line by line of a textfile and if a line meets some requirements I want to override the line and save it at the same position in the same file.
Here is what I have (simplified):
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(){
fstream file;
string line;
file.open("Test.txt");
while (getline(file, line))
{
if (line.size() > 7) file << line.append(" <- long line");
}
}
You can read your file into memory and then write it out after changing any of the lines. The following example reads it into a vector, then writes it back out.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
fstream file;
string line;
file.open("Test.txt", fstream::in);
if (file.fail()) exit(-1);
vector<string> vec;
while (getline(file, line, '\n'))
{
string ln = line;
vec.push_back(ln);
}
file.close();
// manipulate your lines here
file.open("Test.txt", fstream::out | fstream::trunc);
for (vector<string>::iterator it = vec.begin(); it != vec.end(); ++it)
{
file.write(it->c_str(), it->length());
file.write("\n", 1);
}
file.close();
}
But note, when you change a line, the position of lines that follow will change unless the line you are changing is the same size as the original. Also note, this is a simple ANSI file example, but UNICODE and UTF-8 are also common text file formats. This should at least get you started.

C++ Reading Files

What is the minimum code required to read a file and assign its contents to a string in c++?
I did read a lot of tutorials that worked but they were all different in a way so i am trying to see why, so if you could please include some explanatory comments that would be great.
Related: What is the best way to read an entire file into a std::string in C++?
#include <fstream>
#include <string>
int main()
{
std::ifstream file("myfile.txt"); // open the file
std::string line, whole_file;
// Read one line at a time from 'file' and store the result
// in the string called 'line'.
while (std::getline(file, line))
{
// Append each line together so the entire file will
// be in one string.
whole_file += line;
whole_file += '\n';
}
return 0;
// 'file' is closed automatically when the object goes out of scope.
}
A couple of things to note here. getline() returns a reference to the stream object, which fails the while-test if anything bad happens or if you reach the end of the file. Also, the trailing newline is not included in the string, so you have to append it manually.
The shortest code: (not effecient)
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <fstream>
int main()
{
std::ifstream f("plop");
std::string buffer;
std::copy(std::istreambuf_iterator<char>(f),
std::istreambuf_iterator<char>(),
std::back_inserter(buffer));
}
How I would probably do it:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <fstream>
int main()
{
// Find the size of the file
std::ifstream file("Plop");
file.seekg(0,std::ios_base::end);
std::streampos size = file.tellg();
// Read the file in one go.
file.seekg(0);
std::vector<char> buffer(size); // pre-szie the vector.
file.read(&buffer[0],size);
// or
// Until the next version of the standard I don't think string gurantees contigious storage.
// But all the current versions I know do use continious storage so it should workd.
file.seekg(0);
std::string buffer1(size);
file.read(&buffer1[0],size);
}
I'm not seeing as much:
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main() {
ifstream ifs("filename");
stringstream ss;
ss << ifs.rdbuf();
string s = ss.str();
}
... as I'd expect. You'd want some error-checking too.
Konrad Rudolph gave this as the answer to the "related question" linked above. I suppose this isn't a duplicate, since this asks for the shortest code, but the answer is the same either way. So I repost it here as wiki.
I am reading a word from each line.
#include<fstream>
#include<string>
using namespace std;
int main(int argc, char **argv)
{
fstream inFile;
string str;
while(!inFile.eof())
{
inFile.open("file.txt");
infile>>str;
}
inFile.close();
return 0;
}
This is longer than the short solutions, but is possibly slightly more efficient as it does a bit less copying - I haven't done any timing comparisons though:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;;
unsigned int FileRead( istream & is, vector <char> & buff ) {
is.read( &buff[0], buff.size() );
return is.gcount();
}
int main() {
ifstream ifs( "afile.dat", ios::binary );
const unsigned int BUFSIZE = 64 * 1024;
std::vector <char> buffer( BUFSIZE );
unsigned int n;
string s;
while( n = FileRead( ifs, buffer ) ) {
s.append( &buffer[0], n );
}
cout << s;
}
If you know that your file contains text, then you can use STLSoft's platformstl::memory_mapped_file:
platformstl::memory_mapped_file file("your-file-name");
std::string contents(static_cast<char const*>(file.memory()), file.size());
or
platformstl::memory_mapped_file file("your-file-name");
std::wstring contents(static_cast<wchar_t const*>(file.memory()),
file.size() / sizeof(wchar_t));
On WIndows, that will leave your string containing \r\n sequences, so you could instead use the winstl::load_text_file() function:
std::string contents;
winstl::load_text_file("your-file-name", contents);
If you want it loaded into a collection of lines, then use platformstl::read_lines():
platformstl::basic_file_lines<char> lines("your-file-name");
size_t n = lines.size();
std::string line3 = lines[3];