1

I am new to C++ and currently using visual studio.

I see on many tutorials online that when reading from a file with ifstream, before we cout the contents when looping through each line, we write the contents of the current line to a char data[] var then cout the data.

Something like the following

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

int main()
{
        ifstream f("D:\\file1.txt");
        char a[80];

        while(!f.eof())
        {
                f >> a;
                cout << a << endl;
        }

        return(0);
}

What is the point of

char a[80];
...
f >> a;
cout << a << endl;

When we could just do

cout << f << endl;

And save declaring a char and wasting more lines of code?

David G
  • 94,763
  • 41
  • 167
  • 253
cecilli0n
  • 457
  • 2
  • 9
  • 20
  • 6
    I don't know which tutorials you read but they are bad C++ tutorials. You should use `std::string` not `char[]`, `while(!f.eof())` is also wrong [see here](http://stackoverflow.com/q/5605125/583833). – Borgleader Jan 22 '15 at 21:34
  • 6
    Did you trying using `cout << f << endl;`? How did that work out for you? – jwodder Jan 22 '15 at 21:36
  • No you couldn't just do `cout << f << endl;` unless you have overloaded that operator. The better question would be "What is the purpose of storing the content in memory before printing it?". I believe the answer is in the question – smac89 Jan 22 '15 at 21:36
  • 1
    @Smac89: Actually, you could do that pre-C++11. But it certainly wouldn't do what the OP is hoping. It would convert the stream to a `void*` and print its value. – Benjamin Lindley Jan 22 '15 at 21:45
  • Beware of online tutorials. **Get a good book:** https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Galik Jan 22 '15 at 21:50
  • Well that's just an example and you're supposed to do something with your input, not just printing it out – Nikko Jan 22 '15 at 22:10
  • Also think about the hardware architecture. Somebody has to store it in memory, (unless they are trying to read the file one register sized chunk at a time). – josh poley Jan 22 '15 at 22:28

2 Answers2

0

The preferred method in C++ is:

#include<iostream>
#include<fstream>

int main()
{
        std::ifstream f("D:\\file1.txt");

        if( f )
        {
            std::string line;
            while(getline(f, line) )
            {
                std::cout << line << endl;
            }
         }

        return 0 ;
}

If you want to copy, or list files, use operating system commands. The operating system commands are more optimized for handling files. Also, they already exist and have been tested so you don't waste your time.

Nikko
  • 4,182
  • 1
  • 26
  • 44
Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

What is the purpose of storing the content in memory before printing it?

In your example, there isn't much of a point. The data being read from std::cin is being sent directly to std::cout to be displayed on the console. Generally, the only reasons you'd want to store the data in the program memory before printing it is if you want to modify the data or check properties of the data and take certain actions based on those properties.

It should be noted that while this is a common example, the use of while (!eof()) is the incorrect way to check the validity of the stream before reading data. This method checks the stream before the input is read, which can lead to undefined behavior if invalid data is read and subsequently used. The normal way to read data is to check the validity of the stream after performing the read. For example, in your program this would be changed to:

while (f >> a)
{
    std::cout << a << std::endl;
}

After the read is performed, the stream will be converted to a boolean. It will return true or false depending on the validity of the stream. If the stream read the end-of-file (EOF) character then that would be a failed read and the stream will return false.

What is the point of

char a[80];
...
f >> a;
cout << a << endl;

when we could just do

cout << f << endl;

First, cout << f will not do what you expect. The stream insertion operator (operator<<()) is overloaded for certain types. f is of type std::ifstream - a type for which this operator is not overloaded. Pre-C++11 C++ IOStreams contained a conversion to void* so that they could be used in boolean contexts. The stream insertion operator is overloaded for pointers to void, so the output you would get is not something you'd expect. As of C++11 you'd get a compiler error that no operator overload could be found for that type.

There is, however, an overload for std::streambuf*, a pointer an IOStreams buffer. Each stream has a buffer that stores and maintains characters from the source or sink. The overload for this operator reads data from the buffer and sends it to its own buffer, so you can do something like this:

std::cout << f.rdbuf();

rdbuf() returns a pointer to the stream's buffer.

While this is an effective use of the stream's capabilities, the data is still being stored in the buffer of std::cout. Streams are buffered and data sent into the source or sink are consigned to a buffer where it waits until the buffer is flushed. You can use std::nounitbuf to unbuffer std::cout in order to write directly to the external device:

std::cout << std::nounitbuf
          << f.rdbuf();

For a simple example with a small file, buffering really isn't needed. If you have a very large file then buffering is very useful as the program doesn't have to make a system call for each character being inserted.

Community
  • 1
  • 1
David G
  • 94,763
  • 41
  • 167
  • 253