90

I'm in a tutorial which introduces files (how to read from file and write to file)

First of all, this is not a homework, this is just general help I'm seeking.

I know how to read one word at a time, but I don't know how to read one line at a time, or how to read the whole text file.

What if my file contains 1000 words? It is not practical to read entire file word after word.

My text file named "Read" contains the following:

I love to play games
I love reading
I have 2 books

This is what I have accomplished so far:

#include <iostream>
#include <fstream>

using namespace std;
int main (){
   
  ifstream inFile;
  inFile.open("Read.txt");

  inFile >>

Is there any possible way to read the whole file at once, instead of reading each line or each word separately?

Patrick Roberts
  • 40,065
  • 5
  • 74
  • 116
Mody
  • 1,117
  • 2
  • 9
  • 11
  • 4
    There are well-defined answers here: http://stackoverflow.com/questions/551082/c-read-lines-from-file – sampson-chen Oct 23 '12 at 17:09
  • possible duplicate of [How to read a line from a text file in c/c++?](http://stackoverflow.com/questions/3081289/how-to-read-a-line-from-a-text-file-in-c-c) – Adrian McCarthy Oct 23 '12 at 18:20
  • Reading word by word is only marginally slower than line by line. If you actually need words, then it's better to read words. Read lines if you're dealing with line-oriented data such as CSV file. –  Oct 23 '12 at 18:27
  • @Arkadiy that is incorrect. For an 100 MiB file, reading line by line will easily take seconds, while reading a block of 4 KiB at a time seconds less than a second. – vallentin Jul 31 '16 at 08:46
  • @Vallentin: Given that the streams are all buffered, the actual disk reading is done block by block already. The rest is just manipulating data in memory. –  Aug 01 '16 at 13:00
  • @Arkadiy that's funny, because I actually tested the speed yesterday. From fastest to slowest `fread 4 KiB`, `fread 128 bytes`, `std::getline`, `fgetc`, `ifstream::get`. Where `fread` took 0.15 seconds, and `std::getline` took 6 seconds, for a 1 GiB text file. – vallentin Aug 01 '16 at 13:05
  • @Vallentin - did you do anything with the data read? Since the OP ultimately needs words, not blocks, the test needs to split into words. –  Aug 01 '16 at 13:25
  • @Arkadiy didn't do anything to the data besides continuously reading the file until the end. I was in the need of something similar to OP and ended up doing that through `fread 4 KiB`. It worked by having 2 blocks at a time. Thereby if the word (or better said, last word) exceeded the first block, it would continue into the next block. So yes, if the word exceeded 4 KiB in length, then I wouldn't be able to read it. But for me that wasn't the case, and I wanted to limit any copying and moving of memory to preserve speed, and it worked (for my case). – vallentin Aug 01 '16 at 14:28
  • @Vallentin If you need to start from the end of file, you're better off using seek. And then of course it becomes rather hard to use standard streams. I do not see any reference to reading to end of file first in the OP's post, though. –  Aug 01 '16 at 14:31
  • @Arkadiy No no, I needed to get every word separated by spaces in a file. The thing is, if the last char in the buffer isn't whitespace, then the word continues. We (obviously ) can't do `fread` because then we can't get the first part of the word. So the solution was 2 buffers. Again, I was trying to NOT copy any memory from the buffers, which compared to copying every word out, showed a significant speed improvement for files bigger than 100 MiB. – vallentin Aug 01 '16 at 14:52
  • @Vallentin Agreed, 2 buffers and only copy the crossing words would be much faster, but also much trickier for a new user to get right :) If you're to limit yourself to words copied to std::string, then reading words rather than lines probably does not matter. –  Aug 01 '16 at 14:57

7 Answers7

167

You can use std::getline :

#include <fstream>
#include <string>

int main() 
{ 
    std::ifstream file("Read.txt");
    std::string str; 
    while (std::getline(file, str))
    {
        // Process str
    }
}

Also note that it's better you just construct the file stream with the file names in it's constructor rather than explicitly opening (same goes for closing, just let the destructor do the work).

Further documentation about std::string::getline() can be read at CPP Reference.

Probably the easiest way to read a whole text file is just to concatenate those retrieved lines.

std::ifstream file("Read.txt");
std::string str;
std::string file_contents;
while (std::getline(file, str))
{
  file_contents += str;
  file_contents.push_back('\n');
}  
Dr1Ku
  • 2,690
  • 3
  • 43
  • 52
111111
  • 14,528
  • 6
  • 38
  • 58
  • 9
    Although not obvious, `while(getline(f, line)) { ...}` really is the recommended way to do this. This is explained here: http://gehrcke.de/2011/06/reading-files-in-c-using-ifstream-dealing-correctly-with-badbit-failbit-eofbit-and-perror/ --- there you also find useful approaches for proper error handling. – Dr. Jan-Philip Gehrcke Jan 18 '15 at 14:19
  • 1
    The above code will not compile without ```#include ``` – Tyguy7 Aug 16 '15 at 22:28
  • 1
    @Tyguy7 Why would `#include ` be required? It seems to me that `` and `` are enough. If you mean `std::getline`, it is in ``, not in ``. – Fabio says Reinstate Monica Mar 08 '17 at 23:53
  • @FabioTurati I'm not sure, I just know that once I included it, everything compiled fine. – Tyguy7 May 16 '17 at 00:28
20

I know this is a really really old thread but I'd like to also point out another way which is actually really simple... This is some sample code:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    ifstream file("filename.txt");
    string content;

    while(file >> content) {
        cout << content << ' ';
    }
    return 0;
}
Speedphoenix
  • 202
  • 1
  • 6
  • 13
user2673553
  • 293
  • 5
  • 11
  • 2
    Nice answer, I used this with a stringstream instead of cout to get the whole file into a giant stringstream – bjackfly Feb 06 '14 at 19:24
5

I think you could use istream .read() function. You can just loop with reasonable chunk size and read directly to memory buffer, then append it to some sort of arbitrary memory container (such as std::vector). I could write an example, but I doubt you want a complete solution; please let me know if you shall need any additional information.

Bartek Banachewicz
  • 36,624
  • 6
  • 81
  • 129
  • I dont know who downvoted this answer but this is good may be i am not of your standards but I use the same thing – Javasist Oct 25 '12 at 09:16
5

Well, to do this one can also use the freopen function provided in C++ - http://www.cplusplus.com/reference/cstdio/freopen/ and read the file line by line as follows -:

#include<cstdio>
#include<iostream>

using namespace std;

int main(){
   freopen("path to file", "rb", stdin);
   string line;
   while(getline(cin, line))
       cout << line << endl;
   return 0;
}
Community
  • 1
  • 1
AnkitSablok
  • 2,715
  • 5
  • 26
  • 51
1

Another method that has not been mentioned yet is std::vector.

std::vector<std::string> line;

while(file >> mystr)
{
   line.push_back(mystr);
}

Then you can simply iterate over the vector and modify/extract what you need/

Bugster
  • 1,404
  • 8
  • 32
  • 56
0

hello bro this is a way to read the string in the exact line using this code

hope this could help you !

#include <iostream>
#include <fstream>

using namespace std;


int main (){


    string text[1];
    int lineno ;
    ifstream file("text.txt");
    cout << "tell me which line of the file you want : " ;
    cin >> lineno ; 



    for (int i = 0; i < lineno ; i++)
    {
        
        getline(file , text[0]);

    }   

    cout << "\nthis is the text in which line you want befor  :: " << text[0] << endl ;
    system("pause");

    return 0;
}

Good luck !

0

you can also use this to read all the lines in the file one by one then print i

#include <iostream>
#include <fstream>

using namespace std;



bool check_file_is_empty ( ifstream& file){
    return file.peek() == EOF ;
}

int main (){


    string text[256];
    int lineno ;
    ifstream file("text.txt");
    int num = 0;

    while (!check_file_is_empty(file))
    {    
        getline(file , text[num]);
        num++;
    }
    for (int i = 0; i < num ; i++)
    {
        cout << "\nthis is the text in " <<  "line " << i+1 << " :: " << text[i] << endl ;


    }
    
    system("pause");

    return 0;
}

hope this could help you :)