Thread: writing to stdin !

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    84

    writing to stdin !

    I've tried to do the following code:
    Code:
    	int c;
    	fprintf(stdin,"%s","386");
    	c=getchar();
    	putchar(c);
    I though that fprint will put the string in the keyboard buffer, it didn't.
    Can anyone explain why please.

    Many thanks

  2. #2
    Registered User
    Join Date
    Jan 2007
    Location
    Euless, TX
    Posts
    144
    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.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    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.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't think writing to stdin is defined. Is it?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    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.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >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:
    Code:
    #define _put(c,out,n) ( ++n, fputc ( c, out ) )
    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:
    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;
    }
    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.

    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:
    Code:
    #include <stdio.h>
    
    int main ( void )
    {
      printf ( "%d\n", EOF );
      printf ( "%d\n", fputc ( 'a', stdin ) );
      return 0;
    }
    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.

    [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.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Prelude, I'm just a bit curious as to why the following line is necessary in your code:
    Code:
      out->_flag &= ~_READ;
    Since the previous code-segment has checked if this out->_flag & _READ and decided it's not set.

    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.

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >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.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Prelude View Post
    >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.
    Fair 'nuff.

    --
    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.

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    84
    Thank you great stuff!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. Replies: 2
    Last Post: 07-12-2008, 12:00 PM
  3. writing to stdin
    By rokenrol in forum C Programming
    Replies: 8
    Last Post: 07-13-2006, 04:44 AM
  4. Folding@Home Cboard team?
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 398
    Last Post: 10-11-2005, 08:44 AM
  5. help! fifo read problem
    By judoman in forum C Programming
    Replies: 1
    Last Post: 08-16-2004, 09:19 AM