#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
fstream newfile;
newfile.open("tpoint.txt",ios::out); // open a file to perform write operation using file object
if(newfile.is_open()) //checking whether the file is open
{
newfile<<"Tutorials point \n"; //inserting text
newfile.close(); //close the file object
}
newfile.open("tpoint.txt",ios::in); //open a file to perform read operation using file object
if (newfile.is_open()){ //checking whether the file is open
string tp;
while(getline(newfile, tp)){ //read data from file object and put it into string.
cout << tp << "\n"; //print the data of the string
}
newfile.close(); //close the file object.
}
}
#include <fstream>
#include <iostream>
using namespace std;
int main () {
char data[100];
// open a file in write mode.
ofstream outfile;
outfile.open("afile.dat");
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// write inputted data into the file.
outfile << data << endl;
cout << "Enter your age: ";
cin >> data;
cin.ignore();
// again write inputted data into the file.
outfile << data << endl;
// close the opened file.
outfile.close();
// open a file in read mode.
ifstream infile;
infile.open("afile.dat");
cout << "Reading from the file" << endl;
infile >> data;
// write the data at the screen.
cout << data << endl;
// again read the data from the file and display it.
infile >> data;
cout << data << endl;
// close the opened file.
infile.close();
return 0;
}
#include <fstream>
std::ifstream infile("thefile.txt");
5 3
6 4
7 1
10 5
11 6
12 3
12 4
First, make an ifstream
:
#include <fstream>
std::ifstream infile("thefile.txt");
The two standard methods are:
-
Assume that every line consists of two numbers and read token by token:
int a, b; while (infile >> a >> b) { // process pair (a,b) }
-
Line-based parsing, using string streams:
#include <sstream> #include <string> std::string line; while (std::getline(infile, line)) { std::istringstream iss(line); int a, b; if (!(iss >> a >> b)) { break; } // error // process pair (a,b) }
You shouldn't mix (1) and (2), since the token-based parsing doesn't gobble up newlines, so you may end up with spurious empty lines if you use getline()
after token-based extraction got you to the end of a line already.
53
Reading a file line by line in C++ can be done in some different ways.
[Fast] Loop with std::getline()
The simplest approach is to open an std::ifstream and loop using std::getline() calls. The code is clean and easy to understand.
#include <fstream>
std::ifstream file(FILENAME);
if (file.is_open()) {
std::string line;
while (std::getline(file, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
file.close();
}
[Fast] Use Boost's file_description_source
Another possibility is to use the Boost library, but the code gets a bit more verbose. The performance is quite similar to the code above (Loop with std::getline()).
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <fcntl.h>
namespace io = boost::iostreams;
void readLineByLineBoost() {
int fdr = open(FILENAME, O_RDONLY);
if (fdr >= 0) {
io::file_descriptor_source fdDevice(fdr, io::file_descriptor_flags::close_handle);
io::stream <io::file_descriptor_source> in(fdDevice);
if (fdDevice.is_open()) {
std::string line;
while (std::getline(in, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
fdDevice.close();
}
}
}
[Fastest] Use C code
If performance is critical for your software, you may consider using the C language. This code can be 4-5 times faster than the C++ versions above, see benchmark below
FILE* fp = fopen(FILENAME, "r");
if (fp == NULL)
exit(EXIT_FAILURE);
char* line = NULL;
size_t len = 0;
while ((getline(&line, &len, fp)) != -1) {
// using printf() in all tests for consistency
printf("%s", line);
}
fclose(fp);
if (line)
free(line);
Benchmark -- Which one is faster?
I have done some performance benchmarks with the code above and the results are interesting. I have tested the code with ASCII files that contain 100,000 lines, 1,000,000 lines and 10,000,000 lines of text. Each line of text contains 10 words in average. The program is compiled with -O3
optimization and its output is forwarded to /dev/null
in order to remove the logging time variable from the measurement. Last, but not least, each piece of code logs each line with the printf()
function for consistency.
The results show the time (in ms) that each piece of code took to read the files.
The performance difference between the two C++ approaches is minimal and shouldn't make any difference in practice. The performance of the C code is what makes the benchmark impressive and can be a game changer in terms of speed.
10K lines 100K lines 1000K lines
Loop with std::getline() 105ms 894ms 9773ms
Boost code 106ms 968ms 9561ms
C code 23ms 243ms 2397ms
1
What happens if you remove C++'s synchronization with C on the console outputs? You might be measuring a known disadvantage of the default behavior of std::cout
vs printf
. – user4581301 Jul 30 '18 at 20:41
-
2
Thanks for bringing this concern. I've redone the tests and the performance is still the same. I have edited the code to use the
printf()
function in all cases for consistency. I have also tried usingstd::cout
in all cases and this made absolutely no difference. As I have just described in the text, the output of the program goes to/dev/null
so the time to print the lines is not measured. – HugoTeixeira Jul 31 '18 at 2:11 -
6
Groovy. Thanks. Wonder where the slowdown is. – user4581301 Jul 31 '18 at 4:34
-
4
Hi @HugoTeixeira I know this is an old thread, I tried to replicate your results and could not see any significant difference between c and c++ github.com/simonsso/readfile_benchmarks – Simson Feb 3 '19 at 5:24
-
By default, C++ in-out streams are synchronized with
cstdio
. You should have tried with settingstd::ios_base::sync_with_stdio(false)
. I guess you would have obtained way much better performances (It is not guaranteed though since it is implementation-defined when synchronization is toggled off). – Fareanor Dec 9 '19 at 8:39
11
Since your coordinates belong together as pairs, why not write a struct for them?
struct CoordinatePair
{
int x;
int y;
};
Then you can write an overloaded extraction operator for istreams:
std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
is >> coordinates.x >> coordinates.y;
return is;
}
And then you can read a file of coordinates straight into a vector like this:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
char filename[] = "coordinates.txt";
std::vector<CoordinatePair> v;
std::ifstream ifs(filename);
if (ifs) {
std::copy(std::istream_iterator<CoordinatePair>(ifs),
std::istream_iterator<CoordinatePair>(),
std::back_inserter(v));
}
else {
std::cerr << "Couldn't open " << filename << " for reading\n";
}
// Now you can work with the contents of v
}
shareimprove this answerfollow
answered Aug 20 '16 at 16:58
8,31022 gold badges2525 silver badges3232 bronze badges
-
1
What happens when it's not possible to read two
int
tokens from the stream inoperator>>
? How can one make it work with a backtracking parser (i.e. whenoperator>>
fails, roll back the stream to previous position end return false or something like that)? – fferri Dec 1 '16 at 13:31 -
If it's not possible to read two
int
tokens, then theis
stream will evaluate tofalse
and the reading loop will terminate at that point. You can detect this withinoperator>>
by checking the return value of the individual reads. If you want to roll back the stream, you would callis.clear()
. – Martin Broadhurst Jan 7 '17 at 14:10 -
in the
operator>>
it is more correct to sayis >> std::ws >> coordinates.x >> std::ws >> coordinates.y >> std::ws;
since otherwise you are assuming that your input stream is in the whitespace-skipping mode. – Darko Veberic Mar 27 '17 at 17:55
7
Expanding on the accepted answer, if the input is:
1,NYC
2,ABQ
...
you will still be able to apply the same logic, like this:
#include <fstream>
std::ifstream infile("thefile.txt");
if (infile.is_open()) {
int number;
std::string str;
char c;
while (infile >> number >> c >> str && c == ',')
std::cout << number << " " << str << "\n";
}
infile.close();
shareimprove this answerfollow
answered May 18 '17 at 9:35
63.3k3030 gold badges132132 silver badges223223 bronze badges
2
Although there is no need to close the file manually but it is good idea to do so if the scope of the file variable is bigger:
ifstream infile(szFilePath);
for (string line = ""; getline(infile, line); )
{
//do something with the line
}
if(infile.is_open())
infile.close();
shareimprove this answerfollow
answered May 1 '18 at 20:11
38333 silver badges77 bronze badges
-
Not sure this deserved a down vote. OP asked for a way to get each line. This answer does that and gives a great tip of making sure the file closes. For a simple program it may not be needed but at minimum a GREAT habit to form. It could maybe be improved by adding in a few lines of code to process the individual lines it pulls but overall is the simplest answer to the OPs question. – Xandor Sep 18 '19 at 18:22
2
This answer is for visual studio 2017 and if you want to read from text file which location is relative to your compiled console application.
first put your textfile (test.txt in this case) into your solution folder. After compiling keep text file in same folder with applicationName.exe
C:\Users\"username"\source\repos\"solutionName"\"solutionName"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
// open the file stream
inFile.open(".\\test.txt");
// check if opening a file failed
if (inFile.fail()) {
cerr << "Error opeing a file" << endl;
inFile.close();
exit(1);
}
string line;
while (getline(inFile, line))
{
cout << line << endl;
}
// close the file stream
inFile.close();
}
shareimprove this answerfollow
answered Mar 6 '19 at 17:45
36611 silver badge1111 bronze badges
1
This is a general solution to loading data into a C++ program, and uses the readline function. This could be modified for CSV files, but the delimiter is a space here.
int n = 5, p = 2;
int X[n][p];
ifstream myfile;
myfile.open("data.txt");
string line;
string temp = "";
int a = 0; // row index
while (getline(myfile, line)) { //while there is a line
int b = 0; // column index
for (int i = 0; i < line.size(); i++) { // for each character in rowstring
if (!isblank(line[i])) { // if it is not blank, do this
string d(1, line[i]); // convert character to string
temp.append(d); // append the two strings
} else {
X[a][b] = stod(temp); // convert string to double
temp = ""; // reset the capture
b++; // increment b cause we have a new number
}
}
X[a][b] = stod(temp);
temp = "";
a++; // onto next row
}
https://stackoverflow.com/questions/7868936/read-file-line-by-line-using-ifstream-in-c