Thread: Problem about setvbuf()

  1. #1
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37

    Problem about setvbuf()

    Hi all,
    I wrote this to test setvbuf() function, and find answer to flush related
    questions, have some problems, plz have a look at it, thanks.
    Code:
    #include "stdio.h"
    int main(void)
    {
    	int eat;
    	char ch[5];
    	char inbuf[15];
    	char outbuf[10];
    
    	 if( setvbuf ( stdout, outbuf, _IOFBF, sizeof(outbuf)-1) != 0 )
    		printf("Set stdout buffer Error!\n");                         
    /*Question 1:
     *if set _size to sizeof(outbuf), can't work, 
     *so out-buffer also needs '\0' or '\n' to mark end so as to determine 
     *when to flush data to screem? 
     */
    
    	 if( setvbuf (stdin, inbuf, _IOLBF, sizeof(inbuf)-1) == 0 ) 
    		printf ("Enter some text: ");
    	 else
    		printf ("Set stdin buffer Error!\n");
    /*Question 2:
     *may be the same as stdout, so set in-buffer to sizeof(buf)-1
     *is it necessary?
     */ 	  
    	 if ( fgets(ch, sizeof(ch), stdin) != NULL )  
    		  printf ("You entered: %s\n", ch);
    	 
    /* test if buffer for stdin if full, if so, flush it */
    	 if ( !strchr( inbuf, '\n') ) 	
    	{
    		while ((eat = getchar()) != '\n' && eat != EOF)
    		{;}
    	} 
    	
    	 printf( "buffer set for stdin is > %s < \n", inbuf );
    /* Question 3:
     * here we can see there are still characters left in stdin buffer,
     * why? it shouldn't be empty?
     */
    	
    	return 0;
    }
    BTW, look at this
    Code:
    while ((ch = getchar()) != '\n' && ch != EOF)
    question 4:
    why (ch = getchar()) != '\n' isn't good enough to end while loop
    and we need ch != EOF ?

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    > here we can see there are still characters left in stdin buffer, why? it shouldn't be empty?

    setvbuf gives no indication that it has to work on standard streams like stdin or stdout, because these streams are also buffered, to some extent, by the operating system. This is why platform specific options for buffering where made available. So even if a call returns sucessfully there is no guarantee that it worked for your implementation. You could set buffering for your own streams though.

    > why (ch = getchar()) != '\n' isn't good enough to end while loop

    Because it is entirely likely that stdin would be redirected to a file by someone who uses your program. Or they could simply opt to send EOF to the program during input.

  3. #3
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37

    the way it follows

    thanks first.
    because these streams are also buffered, to some extent, by the operating system
    do u mean that even we set buffer (assum it to be buf)for stdin,
    the system doesn't send the characters directly to that buffer?
    instead,the characters get from keyboard are still buffered first in the
    automatically-opened buffer for stdin( aussum it to be bufferX) ?
    so which way below it follows?
    Code:
    char c;
    c=getchar();
    ....
    1. keyboard --->stdin---> c
    2. keyboard --->bufferX--->stdin---> c
    3. keyboard --->bufferX--->c
    4. keyboard --->bufferX--->buf--->c
    5. keyboard --->bufferX--->buf--->stdin--->c
    6. keyboard --->bufferX--->stdin--->buf--->c
    7. keyboard --->buf--->stdin--->c
    or some way else?

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    No, Everything is buffered internally...

    Code:
    input device -> buff/stdin -> C

  5. #5
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37

    difference

    input device -> buff/stdin -> C
    buff/stdin, what it means?
    stdin is a pointer pointing to buff? or stdin equals to buff?
    by performing setvbuf( fp, buf, ..., ...), can't we change the internal
    buffer of fp to buf?
    then it goes this way
    Code:
     input device -> buf -> C
    instead of
    Code:
    input device -> buff/stdin -> C

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    > buff/stdin, what it means?
    stdin is opened way before you get to do anything to it in main and might be unbuffered until you actually do something with the stream (like read off it).However, like I said before, the operating system has its own buffering for keyboard events, which is likely to trump the standard options for stdin that you set in your program.

    > by performing setvbuf( fp, buf, ..., ...), can't we change the internal buffer of fp to buf?
    C's FILE system is likely to be tied to the OS. One of the reasons you could use something like setvbuf is so that you could treat a regular memory block like a custom stream and therefore devise an interface for it.

  7. #7
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37

    setvbuf works...?

    it means setvbuf works...>?
    Code:
    #include "stdio.h"
    int main(void)
    {
    	char inbuf[15];
    	char outbuf[30];
    	char ch[10];
    	puts("input a string(<10):");
    	gets(ch); //addpend '/0' to end, count it.
    	printf("%s\n",ch);
    	printf(" buffer for stdin locates:%x\n", (*stdin)._base);
    	printf(" size for stdin is:%d\n", (*stdin)._bufsiz );
    	printf(" pointer for stdin locates:%x\n\n", (*stdin)._ptr );
    
    	printf(" buffer for stdout locates:%x\n", (*stdout)._base );
    	printf(" size for stdout is:%d\n", (*stdout)._bufsiz );
    	printf(" pointer for stdout locates:%x\n\n", (*stdout)._ptr );
    
    	printf(" inbuf locates:%x\n", inbuf);
    	printf(" outbuf locates:%x\n\n", outbuf);
    	
    	puts("After setvbuf()");
    	
    	setvbuf( stdin, inbuf, _IOLBF, sizeof(inbuf)-1);
    	setvbuf( stdout, outbuf, _IOLBF, sizeof(outbuf)-1);
    	
    	printf("input a string(<10):\n");
    	gets(ch);
    	printf("%s\n",ch);
    
    	printf(" buffer for stdin locates:%x\n", (*stdin)._base );
    	printf(" size for stdin is:%d\n", (*stdin)._bufsiz );
    	printf(" pointer for stdin locates:%x\n\n", (*stdin)._ptr );
    
    	printf(" buffer for stdout locates:%x\n", (*stdout)._base );
    	printf(" size for stdout is:%d\n", (*stdout)._bufsiz );
    	printf(" pointer for stdout locates:%x\n", (*stdout)._ptr );
    
    }

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    You're being way too clever for your own good. Apparently I haven't been clear in my last few posts, so allow me to reiterate: setvbuf is not for common standard streams or files. You use setvbuf not to circumvent standard buffering, but to buffer memory that a pointer points to. With this you can create custom streams that queue up data for you. Honestly, I son't see how opening a file and reading a string into a character array won't work for you.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    One more thing,

    > char outbuf[30];
    Because output can be flushed AFTER main has returned, it means your buffer is no longer valid because the main() context no longer exists.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 05:46 PM