0 Replies - 323 Views - Last Post: 05 March 2010 - 10:50 PM Rate Topic: -----

#1 David W   User is offline

  • DIC supporter
  • member icon

Reputation: 298
  • View blog
  • Posts: 1,839
  • Joined: 20-September 08

C safe readLine ... or read just a part (but don't include '\n'))

Posted 05 March 2010 - 10:50 PM

Description: See program/commentsMy other buffered version of readLine, includes the 'n' char at the end of the line (if the buffer was big enough and the line and 'n' char all fit.) This version gets the whole line into the buffer, bit strips away any 'n' char at the end. See comments in program for more info.
/* c_safe_readline_buffered.c  // test program // */

/* This 'test program' needs a .txt file, as per below, in the working folder */

/* c_safe_readline_buffered.h */

#ifndef _C_SAFE_READLINE_BUFFERED_H_
#define _C_SAFE_READLINE_BUFFERED_H_

#include <stdio.h>

/*
    http://developers-heaven.net/forum/index.php/topic,46.0.html

    1. A safe and fast way to read a line from a file into YOUR ready buffer ...
    2. Or just get the first 'specified number' of char's and ignore the rest.

    Returns 0 when EOF is reached AND the buffer to be returned is EMPTY ...
    otherwise, returns 1 (so last line of file in passed in buffer gets returned)
    Also, len of string in buffer is returned via 'int' pointer variable 'len'
*/

int readLine( FILE* file, char buffer[], int lenBuf, int* len )
{
    int c = 0;

    *len = 0; /* initial length of string, to be input in the buffer, to 0 */
    if( lenBuf > 0 ) buffer[0] = '�';
    if( lenBuf < 2 ) return 0; /* just in case of some crazy buffer length */

    while( (c = fgetc(file)) != EOF  &&  c != 'n' )
    {
        if( *len == lenBuf-1 ) /* return now to prevent overflow */
        {
            /* first ... flush the rest of the line ... if any */
            while( !(c == EOF || c == 'n') ) c = fgetc( file );
            
            /* returns length of the string via pointer variable 'len' */
            buffer[*len] = '�';
            return 1;
        }
        buffer[(*len)++] = c; /* first assign, then get ready for next index */
    }
    buffer[*len] = '�';

    /* if last line is empty ... return 0 ...  */
    if( c == EOF  &&  *len == 0 ) return 0;
    /* else ... */
    return 1;
}

#endif


/* c_safe_readline_buffered.c  // test program begins ... // */

/* #include "c_safe_readline_buffered.h" */
#include <stdlib.h> /* for malloc */
#include <string.h> /* for strlen, strcpy used in main ... */
#include <assert.h>

#define TEST_FILE "testFile11lines.txt"



int main() /* *************************************************************** */
{
    FILE *fp;
    char buf[7];
    char buf2[256];
    char* raggedAry[3]; /* just 3 used here to keep the test data loop small */
    int buflen = sizeof buf / sizeof(char);
    int i, len, lineCount = 0 ;

    /* open the file */
    fp = fopen( TEST_FILE, "r" );
    if( fp == NULL )
    {
         printf( "Error opening '%s'.  Press 'Enter to exit ... '", TEST_FILE );
         getchar();
         return 1;
    }

    /* 1. demo of 'chopping short' ... using just a short buffer */

    printf( "With length of buffer = %d ...n", buflen );
    while( readLine( fp, buf, buflen, &len ) )
    {
        printf( "%2d: ", ++lineCount );
        printf( "strlen=%3d, len=%3d: '%s'n", strlen(buf), len, buf );
    }

    rewind( fp );

    /* 2. demo that doesn't 'chop short' ... using a LARGE enough buffer */
    
    buflen = sizeof buf2 / sizeof(char);
    lineCount = 0;
    printf( "nWith length of buffer = %d ...n", buflen );
    while( readLine( fp, buf2, buflen, &len ) )
    {
        printf( "%2d: ", ++lineCount );
        printf( "strlen=%3d, len=%3d: '%s'n", strlen(buf2), len, buf2 );
    }

    fclose( fp );

    /* 3. demo reading from stdin ... using a LARGE enough buffer */

    buflen = sizeof buf2 / sizeof(char);
    lineCount = 0;
    printf( "nWith length of buffer = %d, ",  buflen );
    puts( "enter data ... or press 'Enter' to Exit ...n" );
    while
    (
        lineCount < sizeof(raggedAry)/sizeof(raggedAry[0]) &&
        printf( "Enter text %03d: ", lineCount+1 ) &&
        readLine( stdin, buf2, buflen, &len )
    )
    {
        if( buf2[0] == 0 ) break;
        assert( (raggedAry[lineCount] = malloc( len+1 )) != NULL );
        strcpy( raggedAry[lineCount++], buf2 );
    }
    
    puts( "nYou entered ..." );
    for( i = 0; i < lineCount; ++i )
    {
        printf( "line %03d: %sn", i+1, raggedAry[i] );
        free( raggedAry[i] );
    }

    printf( "nPress 'Enter' to continue ... " );
    getchar();
    return 0;
} /* ************************************************************************ */

/* testFile11lines.txt = 2 empty lines, 3 with text, 3 empty, 1 text, 2 empty */

/*


The boy, frustrated at his code, turned to DIC.
A
Ab



The girl, perplexed at her code, turned too ...



*/



Is This A Good Question/Topic? 0
  • +

Page 1 of 1