in the following code, getch() is executed before the file is displayed.!
whats wrong? how can i correct this?

void ReadFile()
{	char fname[13],ch;

	cout<<"Enter filename : ";
	cin>>fname;
	strcat(fname,".mth");
	temp.open(fname,ios::in|ios::nocreate);
	if(!temp)
	{	cout<<"File does not exist!!!";
		getch();
		return;
	}
	temp.get(ch);
	while(!temp.eof())
	{	cout.put(ch);
		temp.get(ch);
	}
	temp.close();
	getch();
}

Recommended Answers

All 10 Replies

I'm pretty sure you're making that up, or at least mistaking it.
Do you have a cin.ignore() or cin.get() or something before the function is called?

Also, you should use std::string to read in the file and getline(). It makes it much easier... Also work with lines rather than characters. You could open the file in binary mode and read the whole thing at once if you wanted too... but I can never remember off the top of my head how to do that ;)

#include <string>

// ...

void read_file( void ) {
  std::string line, file, f_name;

  std::cout<< "What's the filename: ";
  std::cin >> f_name;

  temp.open( (f_name+".mth").c_str() ,ios::in|ios::nocreate);

  while ( std::getline( temp, line ) )
    file += line + "\n";

  std::cout<< file;
}

By the way... just ran your code there and it doesn't getch() before reading the file for me, so it must be something in your main() code before the function is called.

does it getch() after the file is displayed???

i've attached my exe file after zipping it!
if you are so much sure i'm lying, u can try executing it.:ooh:
First choose 1 in menu, type anything you like, press ctrl+G after that and save the file when prompted.
then choose 2, the menu is displayed along with the file, without waiting for getch().

The file that you attempt to read is not exist. To track this kind of error, I would suggest you to use std::cout inserting method.

void ReadFile()
{	char fname[13],ch;

	cout<<"Enter filename : ";
	cin>>fname;
	strcat(fname,".mth");
        cout << fname; // to check what string the fname has.
	temp.open(fname,ios::in|ios::nocreate);
	if(!temp)
	{	cout<<"File does not exist!!!";
		getch();
		return;
	}
	temp.get(ch);
	while(!temp.eof())
	{	
                cout << "did it come here"; // check if this part ever process
                cout.put(ch);
		temp.get(ch);
	}
	temp.close();
	getch();
}

The file is opened and read!
only the program doesnot wait after displaying the file, it goes on with displaying the menu.

> getch() is executed before the file is displayed.!
> whats wrong?
The problem is is that you're mixing methods of input and output.

getch() being a low-level, compiler specific function is likely to bypass all the higher level (and probably buffered) functions.

What's worse is that getch() is horribly obsolete to start with, even in C programs, never mind C++ programs.

If you really need to pause, then you need to use a cin method to do the pausing.

Try flushing the stream after the file is printed. cout isn't tied to your file stream, so a read isn't going to force a flush, and I'm willing to bet that the file isn't large enough to fill the stream buffer:

temp.close();
cout.flush();
getch();
commented: that works!!! +1

flushing works.

could you please explain how and why it works?

Note to nitpickers: This article is intentionally simplified.

>could you please explain how and why it works?
cout is a buffered stream, which means that instead of being written individually to the screen right away, the characters are basically being saved in an array called a buffer. This is strictly for performance reasons because it's faster to collect a bunch of things together and push them all out to a device (such as the screen) at once than it is to push them out individually. Think of buffering like dealing with a slow function. The function is slow, so it makes sense to avoid calling it often. The solution is to organize the data so that you don't have to call it often.

When you say cout.put(ch); , you're not actually writing ch to the screen, you're essentially copying ch to an array inside the cout object. That array is then written to the screen when it gets filled up or when some outside force tells it to do so[1]. There are only three times when the buffer is flushed:

  1. The buffer fills up.
  2. The flush member function is called.
  3. A tied stream calls for input.

The first two are simple. If the buffer is full, the whole mechanism would stop working, so cout knows to flush itself automatically. If the flush member function is called, it's like saying "even if the buffer isn't full, flush it anyway". The flush member function is an override for the mechanism so that you can guarantee that the buffer will be flushed and everything gets written to the final destination.

The third is kind of funky. When an output stream is tied to an input stream it means that any request for input from the input stream will automatically cause the output stream to be flushed. cin is tied to cout, which is why this works without any manual flushing:

std::cout<<"Enter a number: ";
std::cin>> num;

If cin weren't tied to cout, you could see the same problem where cin blocks for input before the prompt is displayed. The user wouldn't know what to do because cout hasn't flushed the buffer by the time cin tries to read input.

Now, let's look at your broken code:

temp.get(ch);
while(!temp.eof())
{
    cout.put(ch);
    temp.get(ch);
}
temp.close();
getch();

temp isn't tied to cout (which you can do with the tie member function of temp), so temp.get(ch); doesn't cause cout to be flushed. You also don't call the flush member function of cout anywhere in that loop, so the only other time when cout will be flushed is if the buffer is filled up. If the file isn't bigger than the size of the array inside cout (which you don't know), execution will get to getch without flushing cout. The result is that the contents of the file won't be displayed by the time getch blocks for input, and it appears as if the order of execution is backwards.

By placing an explicit call to cout's flush member function, you guarantee that even if the file is smaller than the size of the buffer, cout is still flushed before getch blocks for input, and everything works as it should.

[1] When the array is finally written, we say that the buffer is being flushed.

Thanks for taking pain to explain!!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.