0

I have a function that reads from a text file and the outputs the whole text file. It looks like this;

string FileInteraction :: read() const
{
    ifstream file;
    string output;
    string fileName;
    string line;
    string empty = "";


    fileName = getFilename();

    file.open(fileName.c_str());

    if(file.good())
    {
        while(!file.eof())
        {
            getline(file, line);
            output = output + line ;
        }

        file.close();
    return output;
    }
    else
        return empty;

};

I call the function like this;

cout << FI.read(); //PS I cant change the way it's called so I can't simply put an endl here

if I use return output + "\n"

i get this as output

-- Write + Read --
This is the first line. It should disappear by the end of the program.

-- Write + Read --
This is another line. It should remain after the append call.
This call has two lines.

I don't want that space to between the lines to be there.

So after the function has been called I need to end the line. How can I do that within the function?

PS. Also if there is a better way to output everything in a text file than the way I have done it i would appreciate any suggestions.

Blobiu5
  • 231
  • 1
  • 3
  • 6
  • 4
    Do not read while not eof. It's broken. Where did you see that? Forget that reference/learning material. It's wrong. A proper read loop would be `while(getline(file, line);`. – R. Martinho Fernandes Aug 06 '13 at 16:41
  • return output + '\n'; ? – doctorlove Aug 06 '13 at 16:42
  • `return output + "\n";` – Andrejs Cainikovs Aug 06 '13 at 16:42
  • I just assumed I would have to use eof as I want to getline while it's not the end of the file, but I suppose your suggestion works too. Just out of interest, why is eof "broken"? – Blobiu5 Aug 06 '13 at 16:45
  • I'd call this pretty bad behavior, though. If your `read()` function is supposed to return the contents of the file, then it should return the contents of the file, and nothing else. If I was using a function that was supposed to return the contents of the file, I wouldn't want it to stick random stuff in there that wasn't in the file it was reading, including newlines at the end. – Crowman Aug 06 '13 at 16:45
  • @doctorlove Ive tried that, it ends up making a blank line underneath which is not what I want. – Blobiu5 Aug 06 '13 at 16:46
  • @Paul Griffiths -> No i don't want to add anything to the file. After ive called the function and the file has been read, when i continue with the other stuff in the program I would like it to start on a new line, not straight after the file has been outputted – Blobiu5 Aug 06 '13 at 16:49
  • 1
    @Blobiu5: Then you need to change the other stuff in the program, not this function. It's very bad design to write your functions to do things that the calling code ought to be doing. If you want stuff to start on a new line after calling this function, then you should start a new line after calling this function, don't try to make the function do that, otherwise you defeat the whole purpose of decomposing operations into functions. – Crowman Aug 06 '13 at 16:52
  • @Blobiu5 http://stackoverflow.com/a/15901308/46642 – R. Martinho Fernandes Aug 06 '13 at 16:52
  • `if( '\n' != *output.rbegin() ) output.append(1, '\n');` So you won't get two if you already have one... –  Aug 06 '13 at 16:53
  • @Blobiu5 I'm not clear what you want in that case. Hopefully enough other people have helped. – doctorlove Aug 06 '13 at 16:55
  • @Paul Griffiths: That's exactly my thoughts on it, however my lecturer has prevented us from changing anything in the main.cpp file so we can't change that call which is ridiculous i think – Blobiu5 Aug 06 '13 at 16:57
  • @Blobiu5: Think about it. Even if you do output `std::endl` in your calling code, if the file itself ends with a newline, you're going to get a blank line, and if the file doesn't end with a newline, you're not. You can try to check whether the file ends with a newline, if you want, but what if the file you're reading ends with 10 blank lines? What are you going to do then? If you want to "output the whole text file", then you can't avoid this. You could always write a second function to take the output from `read()`, and strip any trailing newlines from it, if you wanted. – Crowman Aug 06 '13 at 16:59
  • @Blobiu5: I'm sorry, but I don't have a lot of sympathy for artificial restrictions that force you to write bad code. If you want to "output the whole text file" as you say, then your output will depend entirely on what's in that text file, including the effects of any blank lines at the end. If you don't want to output the whole text file, but you actually want to modify it and add or remove newlines, that's a completely different question. – Crowman Aug 06 '13 at 17:00
  • @Paul Griffiths: No i understand. It's a silly little task the lectrurer has set as an assignment so It's not what I would do either – Blobiu5 Aug 06 '13 at 17:07
  • I sent an e-mail to the lecturer explaining this thing and he has now changed the main.cpp file so that it has the endl after the call of the function – Blobiu5 Aug 06 '13 at 17:09
  • @Blobiu5: But what was the actual assignment? Was it really to "output everything in a text file"? If so, then output everything in the text file, and let the presence or absence of trailing newlines be your lecturer's problem, not yours. – Crowman Aug 06 '13 at 17:09
  • Yeah the thing is the auotamated marking program was marking us down based on our output because we had different output than what the lecturer wanted... it's really stupid... I understand what you're saying though because by adding the endl we are changing the output of what was in the file which is bad practice – Blobiu5 Aug 06 '13 at 17:23
  • 1
    ya know... you can always add another function or two. Have one which only reads a file. Have one which preps for output. Have one at the top level which conforms to external requirements. PS - "I call the function like this;" is incorrect wording. Your professor (or one of his aids) calls your method like that, not you. –  Aug 06 '13 at 17:25
  • Yes, you could always include a `main_how_id_do_it_if_it_wasnt_so_dumb.cpp` file with your submission. – Crowman Aug 06 '13 at 17:39
  • "Automated marking system" that marks you down based on additional blank lines? I despair for the future of the world if this is what our educational system has come to. – Crowman Aug 06 '13 at 17:59

4 Answers4

3

Simply change

return output;

to

return output + "\n";
Kelm
  • 967
  • 5
  • 14
2

This:

So after the function has been called I need to end the line. How can I do that within the function?

is nonsensical. You can't do anything within the function that is supposed to happen after the function has been called. If the calling code doesn't send std::endl to cout when it's supposed to, that's a problem with the calling code, you can't - and shouldn't - try to fix this problem in your function.

Crowman
  • 25,242
  • 5
  • 48
  • 56
0

Simplified:

std::string fileName = getFilename();
std::ifstream file(fileName.c_str());
std::string output;
std::string line;
while (getline(file, line))
    output.append(line);
output.append(1, '\n');
return output;
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
0

simply return output + '\n' instead of just output. '\n' is the escape code for the new line character.