Should I use scanf and printf instead of cin and cout?

I have always been using cin and cout statements. But also I see a lot of people using scanf and printf statements and I've heard it's faster. (okay well faster if you're doing millions of input/output).

I know that scanf and printf are from C so I thought cin and cout would be preferred but that is just my assumption.

So which amongst the two is faster and more importantly is there something one can do that the other can't? Or any other drawbacks or advantages and which do you think should be used?


So which amongst the two is faster and more importantly is there something one can do that the other can't?

One of the biggest advantages of the C++ streams is that they don't require special format specifiers for every type.

and I've heard it's faster.

Until you profile your code and determine that there is a problem stick to C++ streams. The C++ streams are so much safer that the minute speed penalties are not worth the bother, except in possibly very rare circumstances.

So which amongst the two is faster and more importantly is there something one can do that the other can't?

Well easily handling User Defined Types come into mind. Being able to easily print things like C++ strings and types of your own design using operator overloading is a big bonus, IMO. In C every type must have a format specifier or be casted to a standard type, casting can be dangerous. And remember if you inadvertently use the wrong specifier for the type you invoke Undefined Behavior, which is a very bad place to be.

which do you think should be used?

Until you learn enough about the language so that you don't need to make "random" assumptions you should stick to standard C++ language features.

Of course if you really want to be programming in C then by all means use all the C features you want and since C doesn't know anything about C++ you won't need to worry about any C++ features.







So is using std::ios::sync_with_stdio(false); safe as long as I'm not using scanf()? Thanks for the link Thomas and thanks Jib for the reply!

would cin.tie(NULL); make it so that the stream is flushed before every single cin statement? And does this mean that it start input only when cin statement is executed?
Last edited on
> So is using std::ios::sync_with_stdio(false); safe as long as I'm not using scanf()?

Yes. In fact, CoreGuidelines has this recommendation:
'Unless you use printf-family functions call ios_base::sync_with_stdio(false)'
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rio-sync


You may also want to read 'Prefer iostreams for I/O'
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rio-streams
would cin.tie(NULL); make it so that the stream is flushed before every single cin statement?


It is best not to try to mess with the tie between cin and cout. It would be very rare that you would want cout not to be flushed when calling cin.

And does this mean that it start input only when cin statement is executed?

What?

Input from the console is what cin does since "cin" stands for Console INput and "cout" stands for Console OUTput.

"It would be very rare that you would want cout not to be flushed when calling cin" I think you didn't mean to put that "not"..

Can you give an example how how cin.tie(NULL) can be harmful? One application for this would be a quiz program that uses getch() [it's an mcq quiz and we're using getch() because it's spontaneous and takes one input which is exactly what we want], here, this can be a problem if your questions have delays. As if the person clicks a key while the cout statement is under execution, the getch() would have already recognized to take that key that was pressed as input. So the user could mistakely give a wrong answer even thought the question was not even finished displaying!

What I did was use fflush(stdin). I didn't try cin.ignore().

So cin.tie(NULL) would be quite handy.. right? What are demerits for using this? For example does it take a lot of time?

From my understanding, writing this line before cin statements would make it so that the input buffer is flushed when input is encountered.

Also how to toggle this tie()? If it's possible!

"Input from the console is what cin does since "cin" stands for Console INput and "cout" stands for Console OUTput. "

The context was that cin could read from the input buffer even when the cin statement has not been reached.

For example:
1
2
3
4
5
6
7
8
    #include<windows.h> // for sleep
    #include<iostream.h>
    int num;
    cout<<"Type something even though cin has not been encountered yet";
    Sleep(10*1000) // I think sleep takes milliseconds as parameter
    cout<<"Type a number"
    cin>>num;
    cout<<num;


You will notice that when you type after "Type something even though cin has not been encoutered yet" whatever you had typed would go to the cin for num. Similarly with getch.

That's what I originally meant.
"cout" is pronounced "see-out". The "c" stands for "character" because iostreams map values to and from byte (char) representations. - Stroustrup

http://www.stroustrup.com/bs_faq2.html#cout

By default, std::cin is associated with stdin and std::cout is associated with stdout.
(These standard C streams may have been redirected, say, to read from / write to files.)

I think you didn't mean to put that "not"..

Why would you think that?

As if the person clicks a key while the cout statement is under execution, the getch() would have already recognized to take that key that was pressed as input.

What? No. If in the program is in the process of writing to the console input will wait until that operation is complete. Remember that in C/C++ program execution happens from the top down.

What I did was use fflush(stdin).

So you're using a function that according to the standard invokes undefined behavior when used with an input stream. You're lucky if it does anything at all.


So cin.tie(NULL) would be quite handy.. right?

Why would you think that?

You will notice that when you type after "Type something even though cin has not been encoutered yet" whatever you had typed would go to the cin for num. Similarly with getch.

What? You have that "sleep" in then middle so that output normally will not be seen until after that "sleep" finishes and something happens to flush the buffer. With the "Type a number" the buffer will be flushed when the cin is encountered.

By the way you don't seem to understand the purpose of buffering the input and output streams.

Can you give an example how how cin.tie(NULL) can be harmful?

Consider this program:
1
2
3
4
5
6
7
8
#include <iostream>

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout << "enter a number: ";
    int n; std::cin >> n;
}

On some implementations, it is possible that you'll only see "enter a number: " appear on standard output after you've typed in a value for n.

In particular, the stream is flushed at the end of the program when it is destroyed. But there is no guarantee that the stream will be flushed at any point before that. You'd need to do it explicitly:
std::cout << "enter a number: " << std::flush;
Last edited on
This is all to confusing. Let's do this step by step.

Consider the code previously.
1
2
3
4
5
6
7
8
    #include<windows.h> // for sleep
    #include<iostream.h>
    int num;
    cout<<"Type something even though cin has not been encountered yet";
    Sleep(10*1000) // I think sleep takes milliseconds as parameter
    cout<<"Type a number"
    cin>>num;
    cout<<num;


When you type something after "Type something even though cin has not been encoutered yet" after the sleep and when the cin is encountered what you had typed displays on screen.

I thought cin.tie() would prevent that but it seems that is not its use and I don't even know what its use is anymore.

Okay so what can I use to prevent that?

while ((getchar()) != ā€˜\nā€™) deletes only first character and so does fflush(stdin).
cin.ignore(INT_MAX); does not even let me give input


also using cin.ignore(numeric_limits::max(), '\n'); says expected identifier in place of "max()". Also it says argument class list missing


See cout does not take input. It reads from the input buffer. So now how do I clear this input buffer which it reads from? Likewise for getch()/getche() if it's different.
Last edited on

Consider the code previously.

No, let's consider this code instead (complete program with a few more Sleep() calls):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<windows.h> // for sleep
#include<iostream.h>

int main()
{
    int num;
    // You won't see this until after the sleep finishes.
    cout<<"Type something even though cin has not been encountered yet";
 
    Sleep(10*1000) // I think sleep takes milliseconds as parameter.
    // Now let's force a flush() of the stream to insure you see the above output here.
    // fflush(cout);  // Try the program with and without this line to notice if there is any difference.
    cout<<"Type a number"  

    Sleep(10*1000) // I think sleep takes milliseconds as parameter
    // No matter when you enter the value for num, you will not see it until sleep finishes.
    // Also when sleep finishes you should see "Type a number" and be waiting (if you haven't already entered the number) for you to enter the number.
    cin>>num;

    Sleep(10*1000) // I think sleep takes milliseconds as parameter
    
    // Since ending the program flushes() all the output streams you should see this immediately before the program finishes.
    cout<<num;
}


while ((getchar()) != ā€˜\nā€™) deletes only first character

No, this will extract and discard all the characters in the input buffer. By the way you're using C++ so don't use the C-stdio functions like getchar(). Use something like cin.get() instead. It doesn't affect the the output buffer at all.

and so does fflush(stdin).

No, fflush(stdin) produces undefined behavior. This function is only defined to be used with output streams according to the standard. But if it does work then it should fully clean the buffer, but on most systems it just does nothing at all.

also using cin.ignore(numeric_limits::max(), '\n'); says expected identifier in place of "max()". Also it says argument class list missing

That's probably because you forgot to #include a required include file for the use of the numeric_limits class.

See cout does not take input. It reads from the input buffer.

What? I hope you mean cin in the above, because cout has nothing to do with the input buffer. The cout stream, by default, has it's own buffer that information is written into. This buffer will be flushed by several different mechanisms. Which include the buffer reaches capacity, you manually flush the output buffer by using either flush() of endl(), or inputting something into the input buffer with cin.

Likewise for getch()/getche() if it's different.

Well since using these non-standard functions is outdated even in C, you shouldn't even be using these horrible functions in C++.





closed account (E0p9LyTq)
@jlb, did you actually try to compile that code? Missing semi-colons everywhere.

And #include <iostream.h> ? Really? That hasn't been legal for quite some time.
Ugh you see all this confusion is because I'm not compiling I'm just writing this from the best of my memory I probably have most things wrong. Oh and I meant cin when I said cout ;p.

You see, I'm concerned about the input stream.

You know how you could type something when the compiler was at sleep? So you were typing to the input stream. And when cin is reached, it displays the input stream.

So say if in sleep you had typed "cheese", when the cin statement was reached, it would display "cheese" and let you continue typing if you had not pressed enter.

I think if you had pressed enter, then the cin call would have never let you type anything.


What I want to happen is that when it comes to the cin call, whatever was typed previously must be neglected.

Sorry for the confusion.
closed account (E0p9LyTq)
Being concerned about something, without actually testing a compiled program.

That is really not good.

Test your concern and should there be a substantial bottleneck or unexpected behavior then you can consider alternatives.
did you actually try to compile that code? Missing semi-colons everywhere.

Obviously not. The code won't compile for me because of the Windowisms.

And as far as the missing semicolons, not everywhere, only at the end of the silly Sleep() call which I cut and pasted from the OP's code.

And #include <iostream.h> ?

That was also just cut and pasted from the OP's code.

Thanks for pointing out the problems.

@FurryGuy this question was killing me and my computer is having some issues right now.
Topic archived. No new replies allowed.