I've tried to do the following code:
I though that fprint will put the string in the keyboard buffer, it didn't.Code:int c; fprintf(stdin,"%s","386"); c=getchar(); putchar(c);
Can anyone explain why please.
Many thanks
I've tried to do the following code:
I though that fprint will put the string in the keyboard buffer, it didn't.Code:int c; fprintf(stdin,"%s","386"); c=getchar(); putchar(c);
Can anyone explain why please.
Many thanks
As my book tells me, "fprintf" operates with files. So fprintf would take a file pointer as a parameter. In the case you have, stdin is used to read FROM THE CONSOLE, not write to it! If you want to do that, then use stdout.
There is a way to "stuff" the keyboard buffer. That's just a memory area. Where it is, how large, etc., is system dependent.
Stdin is an input stream. Fprintf() will work with streams, (of course), but doesn't write into input streams, only output streams.
stdin is "opened/created" with something akin to.Code:stdin = fopen("console", "r");
The fact that stdin is part of the standard IO and predefined by the runtime system, rather than a user-created file doesn't change the way it's being used or what that file does.
You can't "write" to a file that is opened for "read only", no matter which file it is. What happens if you do that is entirely system dependant and definitely in the undefined behaviour realm - for instance, little green men may turn up in the office cubicle where you sit, or the computer may sprout wings and fly away [like drinking Red Bull ?]. But more likely, it will just not do anything - just discard the data and possibly set errno - or that it crashes because it attempts to access some file-buffer portion that isn't valid.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
>Can anyone explain why please.
The exact "why" depends on your implementation. The abstract "why" is that the fprintf isn't defined for input streams, so what you're trying to do is undefined. But for completeness, here's the "why" for one possible implementation[1]. Let's say that the printing of characters in fprintf boils down to this little guy:
Rather anticlimactic, I know, but fprintf still does a lot of work. Taking a look at fputc, we can see what's going on in that particular logic:Code:#define _put(c,out,n) ( ++n, fputc ( c, out ) )
The exact representation of the _flag member isn't necessary. How it's used is relatively simple. Likewise, _deque_pushf, _deque_full, and _intern_flush aren't relevant because it's the first if statement that we're interested in.Code:int fputc ( int c, FILE *out ) { /* The stream must be open and ready for writing */ if ( !( out->_flag & _OPEN ) || out->_flag & _READ ) { return EOF; } /* Reset the stream to write mode */ out->_flag &= ~_READ; out->_flag |= _WRITE; _deque_pushf ( out->_buf, (char)c ); if ( ( out->_flag & _LBF && c == '\n' ) /* Line buffered; flush on '\n' */ || out->_flag & _NBF /* Non-buffered; always flush */ || _deque_full ( out->_buf ) ) /* Full buffer; always flush */ { if ( _intern_flush ( out ) != 0 ) return EOF; } return c; }
This test is a likely implementation. It checks to make sure that the stream is initialized, and it also checks to see if the stream is oriented properly. stdout would be open and in write mode, but stdin would be open and in read mode, which fails the test and causes fputc to return EOF. I'd wager a guess that "undefined behavior" in the case of the following program will be to print the same value twice for any reasonably intelligent implementation:
So the "why" is that your implementation was probably looking out for that kind of code. Because allowing it would trash at least one buffer internally and place the standard streams into an unpredictable state, it simply disallowed the operation.Code:#include <stdio.h> int main ( void ) { printf ( "%d\n", EOF ); printf ( "%d\n", fputc ( 'a', stdin ) ); return 0; }
[1] It's probably overkill to pull out my example stream implementation, but I will anyway.
My best code is written with the delete key.
Prelude, I'm just a bit curious as to why the following line is necessary in your code:
Since the previous code-segment has checked if this out->_flag & _READ and decided it's not set.Code:out->_flag &= ~_READ;
Obviously no harm in doing it, but it seems unnecessary.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
>I'm just a bit curious as to why the following line is necessary in your code
Clarity. I wanted it to be absolutely obvious that _READ and _WRITE are mutually dependent modes.
My best code is written with the delete key.
Thank you great stuff!