A
arnuld
I have created a program to print the input words on stdout. Input is
taken dynamically from stdin. In each word, each input character is
allocated dynamically. I have ran this program with a file containing a
*single* word made of 25525500 letters and this program works fine on it.
I will welcome any suggestions for improvement.
/* * A program that will ask the user for input and then will print the words on stdout
* and will also count the number of words entered.
* Since I did not want to put any limitation on input size in this program, I have used
* dynamic memory allocation to solve the problem. My intent in creating and then solving
* this problem was purely of learning dynamic memory allocation in C (as defined by ANSI
* standard) and nothing else.
*
* Reagrding storing input words, since there is no agreed definition of what a word is, I
* have taken a very simple approach to it:
*
* Any contiguous collection of characters, containging anything
* except single or multiple whitespace(s), is a word.
*
* VERSION 1.0
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum { WORD_SIZE = 2, WORD_ALLOC_SIZE = 2 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;
int get_single_word( char**, unsigned long* );
int allocate_new_mem( char**, char**, size_t* );
int main( void )
{
char* pword = NULL;
unsigned long letter_count = 0;
size_t word_count = 0;
while( (GSW_OK == get_single_word(&pword, &letter_count)) && ( *pword != 0) )
{
printf("You entered: [%s] - containing %ld alphabets\n", pword, letter_count);
++word_count;
free( pword );
}
printf("word count = %d\n", word_count);
return 0;
}
/* I know somehwere else in this program I should differentiate between the real End of File
* (a.k.a no more input) and the not so real End of File (a.k.a error in input) and at clc I
* got a suggestion to use getc(stdin) and feof() and ferror() for that but I am quite incapable
* of using it. I lack the skill to apply that feature.
*/
int get_single_word( char** ppc, unsigned long* Lcnt )
{
unsigned ele_num = 0;
int ch = EOF;
size_t word_length = WORD_SIZE;
char* word_begin = NULL;
*ppc = malloc(word_length * sizeof(**ppc));
word_begin = *ppc;
if( NULL == *ppc ) return GSW_ENOMEM;
while( (EOF != (ch = getchar())) && isspace(ch) )
{
continue; /* Leading whitespace */
}
if( EOF != ch )
{
*word_begin++ = ch;
ele_num = 1;
}
while( (EOF != (ch = getchar())) && (! isspace(ch)) )
{
if( (word_length - 1) == ele_num++ )
{
if( allocate_new_mem( ppc, &word_begin, &word_length ) )
{
return GSW_ENOMEM;
}
}
*word_begin++ = ch;
}
*word_begin = '\0';
*Lcnt = ele_num;
return GSW_OK;
}
int allocate_new_mem( char** moving_p, char** begin_p, size_t* pwl )
{
char* new_mem = NULL;
new_mem = realloc( *moving_p, (WORD_ALLOC_SIZE * (*pwl) * sizeof *new_mem));
if( new_mem )
{
*begin_p = new_mem + ( *begin_p - *moving_p );
*pwl *= WORD_ALLOC_SIZE;
*moving_p = new_mem;
}
else
{
*begin_p = '\0';
return GSW_ENORESIZE;
}
return GSW_OK;
}
taken dynamically from stdin. In each word, each input character is
allocated dynamically. I have ran this program with a file containing a
*single* word made of 25525500 letters and this program works fine on it.
I will welcome any suggestions for improvement.
/* * A program that will ask the user for input and then will print the words on stdout
* and will also count the number of words entered.
* Since I did not want to put any limitation on input size in this program, I have used
* dynamic memory allocation to solve the problem. My intent in creating and then solving
* this problem was purely of learning dynamic memory allocation in C (as defined by ANSI
* standard) and nothing else.
*
* Reagrding storing input words, since there is no agreed definition of what a word is, I
* have taken a very simple approach to it:
*
* Any contiguous collection of characters, containging anything
* except single or multiple whitespace(s), is a word.
*
* VERSION 1.0
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum { WORD_SIZE = 2, WORD_ALLOC_SIZE = 2 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;
int get_single_word( char**, unsigned long* );
int allocate_new_mem( char**, char**, size_t* );
int main( void )
{
char* pword = NULL;
unsigned long letter_count = 0;
size_t word_count = 0;
while( (GSW_OK == get_single_word(&pword, &letter_count)) && ( *pword != 0) )
{
printf("You entered: [%s] - containing %ld alphabets\n", pword, letter_count);
++word_count;
free( pword );
}
printf("word count = %d\n", word_count);
return 0;
}
/* I know somehwere else in this program I should differentiate between the real End of File
* (a.k.a no more input) and the not so real End of File (a.k.a error in input) and at clc I
* got a suggestion to use getc(stdin) and feof() and ferror() for that but I am quite incapable
* of using it. I lack the skill to apply that feature.
*/
int get_single_word( char** ppc, unsigned long* Lcnt )
{
unsigned ele_num = 0;
int ch = EOF;
size_t word_length = WORD_SIZE;
char* word_begin = NULL;
*ppc = malloc(word_length * sizeof(**ppc));
word_begin = *ppc;
if( NULL == *ppc ) return GSW_ENOMEM;
while( (EOF != (ch = getchar())) && isspace(ch) )
{
continue; /* Leading whitespace */
}
if( EOF != ch )
{
*word_begin++ = ch;
ele_num = 1;
}
while( (EOF != (ch = getchar())) && (! isspace(ch)) )
{
if( (word_length - 1) == ele_num++ )
{
if( allocate_new_mem( ppc, &word_begin, &word_length ) )
{
return GSW_ENOMEM;
}
}
*word_begin++ = ch;
}
*word_begin = '\0';
*Lcnt = ele_num;
return GSW_OK;
}
int allocate_new_mem( char** moving_p, char** begin_p, size_t* pwl )
{
char* new_mem = NULL;
new_mem = realloc( *moving_p, (WORD_ALLOC_SIZE * (*pwl) * sizeof *new_mem));
if( new_mem )
{
*begin_p = new_mem + ( *begin_p - *moving_p );
*pwl *= WORD_ALLOC_SIZE;
*moving_p = new_mem;
}
else
{
*begin_p = '\0';
return GSW_ENORESIZE;
}
return GSW_OK;
}