fileI/O

#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.
   }
}

 

Live Demo

#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:

  1. Assume that every line consists of two numbers and read token by token:

    int a, b;
    while (infile >> a >> b)
    {
        // process pair (a,b)
    }
    
  2. 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 using std::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 setting std::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 

add a comment

 

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

 

Martin Broadhurst

8,31022 gold badges2525 silver badges3232 bronze badges

  • 1

    What happens when it's not possible to read two int tokens from the stream in operator>>? How can one make it work with a backtracking parser (i.e. when operator>> 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 the is stream will evaluate to false and the reading loop will terminate at that point. You can detect this within operator>> by checking the return value of the individual reads. If you want to roll back the stream, you would call is.clear(). – Martin Broadhurst Jan 7 '17 at 14:10 

  • in the operator>> it is more correct to say is >> 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 

add a comment

 

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

edited Nov 25 '17 at 22:18

answered May 18 '17 at 9:35

 

gsamaras

63.3k3030 gold badges132132 silver badges223223 bronze badges

add a comment

 

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

 

Vijay Bansal

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

add a comment

 

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

 

Universus

36611 silver badge1111 bronze badges

add a comment

 

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值