1

I would like to read and display the content of a file entered by user at run-time

My code :

#include<iostream>
#include<fstream>
#include<stdio.h>
using namespace std;
int main()
{
    char fileName[30], ch;
    fstream fp;
    cout<<"Enter the Name of File: ";
    gets(fileName);
    fp.open(fileName, fstream::in);
    if(!fp)
    {
        cout<<"\nError Occurred!";
        return 0;
    }
    cout<<"\nContent of "<<fileName<<":-\n";
    while(fp>>noskipws>>ch)
        cout<<ch;
    fp.close();
    cout<<endl;
    return 0;
}

output :

C:\Users\prade\Desktop>g++ -o file file.cpp&file.exe
Enter the Name of File: tt.txt

Content of tt.txt:-
Hello , I am c++.
I am from us.
I am a programmer.

C:\Users\prade\Desktop>

I want to set the content of file to value of string str. I want to print the whole file's content by using cout<<str;

How can I do that ?

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
Poorvaja
  • 51
  • 2
  • 8
  • use std::getline – fana Jun 10 '22 at 04:21
  • Are you asking how to load an entire file into a single `std::string` object? Or are you asking how to enumerate a file, line by line, using a `std::string` object? Or.. something else? – WhozCraig Jun 10 '22 at 04:21
  • 1
    And if you just want to display the entire file verbatim, you don't need a string to do it. Forget the intermediate string and just open the file, *check to make sure it opened*, then dump `std::cout << fp.rdbuf()` . – WhozCraig Jun 10 '22 at 04:27
  • how to load an entire file into a single `std::string`? – Poorvaja Jun 10 '22 at 04:28
  • `gets` into a fixed size `char` array? WHY?!? [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/q/1694036/364696) You're writing 1) C++ in 2) Anytime after 1999 (when `gets` was deprecated in C for good reason). Just use `std::string` and `std::getline` and never touch C-style strings, let alone `gets`. – ShadowRanger Jun 10 '22 at 04:33
  • @Poorvaja you can consider to upvote useful answer(s). See here: https://stackoverflow.com/help/why-vote. – wohlstad Jun 10 '22 at 05:19
  • Paths are regularly much longer than `30` char (Linux has `4096` chars). C++17 adds a [std::filesystem::path](https://en.cppreference.com/w/cpp/filesystem/path/path) to make path handling simple and robust. – David C. Rankin Jun 10 '22 at 05:50

2 Answers2

0

Instead of extracting a single character from stream, you get extract a complete line using getline(). Your while loop should be something like this:

std::string line, contents;
while(getline(fp, line)) {
    contents += line;
    contents += "\n";
}
std::cout << contents;

Note that the above method is not efficient.

Aamir
  • 1,974
  • 1
  • 14
  • 18
  • It's quite inefficient to do it this way, because every line will cause a [potential] reallocation and copy of the std::string. – wohlstad Jun 10 '22 at 05:03
  • I totally agree, but @Poorvaja wants to read the file line by line. – Aamir Jun 10 '22 at 05:13
0

If you need to read the whole content of a text file into a std::string, you can use the code below.

The function ReadTextFile uses std::ifstream ::rdbuf to extract the content of the file into a std::stringstream. Then it uses std::stringstream::str to convert into a std::string.

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

bool ReadTextFile(std::string const & fileName, std::string & text)
{
    std::stringstream strStream;
    std::ifstream fileStream(fileName);
    if (!fileStream.is_open())
    {
        return false;
    }
    strStream << fileStream.rdbuf();
    fileStream.close();
    text = strStream.str();
    return true;
}

int main() 
{
    std::string text;
    if (!ReadTextFile("t.txt", text))
    {
        std::cout << "failed" << std::endl;
        return 1;
    }
    std::cout << text << std::endl;
    return 0;
}

A side note: better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?.

wohlstad
  • 12,661
  • 10
  • 26
  • 39