setbuf does not seem to work.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Jacko123
    New Member
    • Jan 2010
    • 1

    setbuf does not seem to work.

    Hi all,

    I'm trying to understand how setbuf works and came across this from google for setbuf.
    http://www.cplusplus.c om/reference/clibrary/cstdio/setbuf/
    With fully buffered streams, writing operations are not intended to be written directly to the device associated with them; the data is accumulated in the buffer and written to the device as a block when it is filled.

    I have written a simple c program to accomplish the above, but the code does not seem to work. read_char [line 65 and 67 does not read the character from the file after the buffer is full. Can someone please help me to correct my understanding?

    The following is the logic:
    Step1 : Open file for read and write i.e "w+"
    Step2 : setbuf for buffer of size 5 bytes i.e setbuf(fp, buffer)
    Step3 : Keep writing a character 'A' until the buffer is full in a for loop.
    Step 3.1 : Write a char 'A' to file
    Step 3.2 : Get the cur file position
    Step 3.3 : rewind and read a char
    Step 3.4 : if the char read in 3.3 is 'A', return as the program fails.
    Step 3.5 : Set the file pointer back to cur_pos
    Step4 : Write one more char 'A' to the file after the buffer is full
    Step5 : Read the char from the file, after rewinding. The read_char should have a 'A'.

    Code:
    #include<stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    char* buffer = NULL;
    #define BUF_SIZE            5	
    int counter  = BUF_SIZE;
    const char write_char = 'A';
    char read_char;
    fpos_t cur_pos = -1;
    
    FILE * fp = fopen( "test", "w+" );
    if( !fp )
    {
    	return 1;
    }
    
    buffer = (char *)malloc(BUF_SIZE);
    
    if( !buffer )
    {
    	return 1;
    }
    
    setbuf( fp, buffer );
    
    /* Keep writing until the buffer is full */
    for ( ; counter ; counter-- )
        {
            /* Write character 'A' to the file */
            if( fputc( write_char, fp ) == EOF )
                {
                    /* writing char failed */
    				return 1;
                }                
              
             /* remember the file pointer position */	           
              fgetpos ( fp, &cur_pos );
     
              rewind( fp );
    
              read_char = fgetc( fp );
    
              if( 'A' == read_char )	
              {
                     return 1;
              }
    
            /* Set the file pointer to the position it was last written */ 	
             fseek( fp, cur_pos, SEEK_SET );	
        }
    
    /* Counter is 0 here and hence the buffer is full */
    
    /* Write character 'A' to the file , after the buffer full condition */
    if( fputc( write_char, fp ) == EOF )
         {
               /* writing char failed */
               return 1; 
         }              
    
    fgetpos ( fp, &cur_pos );
    rewind(fp);
    [B]read_char = fgetc( fp );[/B]fseek( fp, cur_pos, SEEK_SET );
    
    [B]if( 'A' != read_char )	// I'm expecting read_char to have 'A' as the buffer is full 
         {
    		 return 1;
         }[/B]
    fseek( fp, cur_pos, SEEK_SET );
    return 0;
    }
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    You have not read you own reference correctly (or fully). setbuf assumes that the buffer passed to it is BUFSIZ bytes long. BUFSIZ is defined in stdio.h, on my version of MinGW and in VC++ 2008 it is defined to 512 which is not too surprising as that is the size of a harddisk sector.

    By defining your buffer to be 5 bytes long all you have done in invoked undefined behaviour as the streaming routines will have assumed that you passed a buffer of the correct size (512 bytes) and will be writing outside the bounds of your array.

    Comment

    Working...