0

Hi i am trying to pass a whole file into a string. This is my Code but the program is always exiting on the first if(). I just can't get behind what i am doing wrong here.

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

std::string readFile (std::string filename);

int main() {
    std::string filename;
    std::string Eingabestring;

    std::cout << "Geben Sie eine Datei an" << std::endl;
    std::cin >> filename;
    Eingabestring = readFile(filename);

    std::cout << Eingabestring << std::endl;

    return 0;
}

std::string readFile (std::string filename)
{
    std::string zeile,inhalt ;
    std::ifstream quelle;
    quelle.open(filename.c_str());

    if (!quelle)
    {
        std::cerr << filename << " kann nicht geöffnet werden!\n";
        return exit(-1);
    }

    while (!quelle.eof())
    {
        getline(quelle,zeile);
        inhalt = inhalt + zeile;
    }

    return inhalt;

}

Already thanks for your help!

Edit: I just noticed that i put the file into a wrong folder.. But the code still isn't reading the whole file. Just the first line, but i thought with the loop i could get every line of my file into the string?

And i fixed the second return 0 to exit(-1). Thats better right?

  • 1
    Not this particular issue, but you should read [Why is `iostream::eof` inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). – molbdnilo Jun 07 '17 at 18:25
  • 2
    You can still inspect why `quelle.open(filename.c_str());` actually failed using `errno` and `perror()`. There are many reasons why that could happen. – πάντα ῥεῖ Jun 07 '17 at 18:27
  • 1
    Most likely the file will not be found because you are entering a *relative* file path like `myfile.txt`. The system will look for the file in the current working directory of the application, which depends on many factors. Try entering the absolute path of the file like `C:\myfile.txt`. – zett42 Jun 07 '17 at 18:33
  • BTW, `return 0;` from a function that returns a `std::string` is a bad idea. – molbdnilo Jun 07 '17 at 18:37
  • 1
    Possible duplicate of [Read whole ASCII file into C++ std::string](https://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring) – Mike Kinghan Jun 07 '17 at 18:45
  • Ah ok. I am using cLion to code and didn't notice where it build my program and noticed that i put it into a wrong folder.. and i edited my question –  Jun 07 '17 at 20:34

2 Answers2

1

Other than checking to see why the open() failed as explained in the comments also keep in mind that there are easier ways to check for when you have hit the end of file in a while loop where you are reading from an istream.

The idiomatic way to loop and read from an istream in C++ is to embed the read expression that returns a reference to the istream in the loop condition, so change your code to

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main() {
    auto character = char{};
    auto file_string = string{};
    while (cin.get(character)) {
        file_string += character;
    }

    cout << file_string << endl;
    return 0;
}

I've used cin above but just replace cin with your file stream object and everything should work normally.

Note that the while terminating condition is now an istream reference, and that is convertible to bool, so the loop will exit when the istream object is done reading or when the stream encounters any errors besides EOF. You don't have to check for eof() yourself.

Also another thing is to pass strings that you do not intend to modify by const reference instead of by value, so the readFile() function should accept a const string& instead of a string, this will help save you string copying. When C++17 is available replace that const string& with std::string_view

Curious
  • 19,352
  • 6
  • 45
  • 114
  • _the loop will exit when the istream object is done reading_ ... I would add that the loop also exits if the stream encounters any error besides `EOF`. – zett42 Jun 07 '17 at 18:39
  • @zett42 updated my answer – Curious Jun 07 '17 at 18:41
  • What is the benefit of writing `auto var = type{};` instead of just `type var;` or maybe `type var{};` if you want to make sure to always initialize? – zett42 Jun 07 '17 at 18:45
  • @zett42 nothing at all, just habit – Curious Jun 07 '17 at 18:46
  • @Curious thats not working for me because. I want to read the file line by line and not each character. I actually need to analyze a file and i still don't know how to do it but my professor gave me that while(){} as a hint. So i thought i have to use it. Also i updated my questions. –  Jun 07 '17 at 21:04
0

Try something like this to read your file instead:

std::string readFile (std::string filename)
{
   std::ifstream quelle(filename);

   std::string content( (std::istreambuf_iterator<char>(quelle) ),
                      (std::istreambuf_iterator<char>()) );
   return content;
}
Jayson Boubin
  • 1,355
  • 2
  • 8
  • 17