print the dynamic input

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;
}
 
M

Michael

arnuld said:
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;
}
compiler warning

abc.c: In function ‘main’:
abc.c:46: warning: format ‘%d’ expects type ‘int’, but argument 2 has
type ‘size_t’


Suggested improvement:
Change %d into %zd

(I'm doing a complete rewrite of it.)
 
M

Michael

Michael said:
arnuld said:
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;
}
compiler warning

abc.c: In function ‘main’:
abc.c:46: warning: format ‘%d’ expects type ‘int’, but argument 2 has
type ‘size_t’


Suggested improvement:
Change %d into %zd

(I'm doing a complete rewrite of it.)

/* new version */
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>

size_t word_count=0,letter_count=0;
bool prev_whitespace=true;
int c;

void closing()
{
printf("] - containing %zd alphabets\n",letter_count);
}

void whitespace_handle()
{
if(!prev_whitespace)
{
closing();
word_count++;
letter_count=0;
}
prev_whitespace=true;
}


int main(void)
{
while((c=getchar())!=EOF)
{
if(isspace(c))
whitespace_handle();
else
{
if(prev_whitespace)
printf("You entered: [");
prev_whitespace=false;
putchar(c);
letter_count++;
}
}
whitespace_handle();
printf("word count = %zd\n",word_count);
return 0;
}
 
V

vippstar

compiler warning

abc.c: In function ‘main’:
abc.c:46: warning: format ‘%d’ expects type ‘int’, but argument 2 has
type ‘size_t’

Suggested improvement:
Change %d into %zd

(I'm doing a complete rewrite of it.)

That's wrong - zd is for the corresponding integer type of size_t,
which is not specified which one it is in the C99 standard.
To print size_t, you'd use zu, zo, zx etc.
 
S

s0suk3

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.

Well, that's very inconvenient. C's memory allocation functions aren't
very handy for working with strings whose size must change
dynamically, as you can see from the mess in this program. My
suggestion, if you find yourself having to do this kind of thing
often, would be to design a good 'string' type that handles memory
(re)allocation issues under the hood.
   *
   * 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);
^^^

That should be '%lu'.
      ++word_count;
      free( pword );
    }

  printf("word count = %d\n", word_count);
^^

And that should be '%zu'.
  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.
 */

feof(stream) -- nonzero if a previous read operation on 'stream'
encountered end-of-file
ferror(stream) -- nonzero if a read or write error occurred on a
previous operation on 'stream'
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';

'*begin_p' has type 'char *'. The '\0' escape sequence has the value
0, so you'll be assigning a null pointer to '*begin_p'. Are you sure
that's what you intended to do?
      return GSW_ENORESIZE;
    }

  return GSW_OK;

}

Sebastian
 
B

Ben Bacarisse

Michael said:
/* new version */
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>

size_t word_count=0,letter_count=0;
bool prev_whitespace=true;
int c;

With every variable declared at file scope? This does not set a good
style example!
int main(void)
{
while((c=getchar())!=EOF)
{
if(isspace(c))
whitespace_handle();
else
{
if(prev_whitespace)
printf("You entered: [");
prev_whitespace=false;
putchar(c);
letter_count++;
}
}
whitespace_handle();
printf("word count = %zd\n",word_count);
return 0;
}

OK, but the original is a stage in long-running exercise to write out
a sorted list of words -- hence all the effort of storing them.
 
A

arnuld

Well, that's very inconvenient. C's memory allocation functions aren't
very handy for working with strings whose size must change
dynamically, as you can see from the mess in this program. My
suggestion, if you find yourself having to do this kind of thing
often, would be to design a good 'string' type that handles memory
(re)allocation issues under the hood.


I will use C++ then. Don't get angry but I *have* to use C here. I am
doing Socket Programming + whole lot of other communication Techie things
that I am fixed on C most of the times. The actual cause is related with
my job responsibility, not with the language itself.

But does anyone think that I *should* create my own string library if
strings are used often in my programs ?



      printf("You entered:  [%s] - containing %ld alphabets\n",
pword, letter_count);
^^^

That should be '%lu'.


ouch!

^^
And that should be '%zu'.

[arnuld@dune ztest]$ gcc4 -ansi -pedantic -Wall -Wextra word-count.c
word-count.c: In function ‘main’:
word-count.c:46: warning: ISO C90 does not support the ‘z’ printf length modifier
[arnuld@dune ztest]$



'*begin_p' has type 'char *'. The '\0' escape sequence has the value 0,
so you'll be assigning a null pointer to '*begin_p'. Are you sure that's
what you intended to do?


Oh.. no, I wonder why the program did not crash wit this bug. Changed to
**begin_p = '\0';

BTW, **begin = 0; will also be a good idea ? (because of implicit
conversion)




-- arnuld
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is now UnBlocked :)
 
A

arnuld

OK, but the original is a stage in long-running exercise to write out
a sorted list of words -- hence all the effort of storing them.


Yippee...yaaa.... .. Hallelujah

Ben you remember it :)
 
N

Nick Keighley

note: "often". I define "often" as twice or thrice.

I will use C++ then. Don't get angry but I *have* to use C here.

why? I mean really why? Is there no C++ compiler
for your platform? Are your boss/collegues allergic to C++?
I am
doing Socket Programming + whole lot of other communication Techie things
that I am fixed on C most of the times. Do you have to interface
with existing C libraries.

I like C, but the "must use C" seems odd.

anything you can do in C you can do in C++. Do you have to interface
with existing C libraries?

The actual cause is related with
my job responsibility, not with the language itself.
?

But does anyone think that I *should* create my own string library if
strings are used often in my programs ?

yes. Or at the very least hide all the nasty dynamic
memory stuff away in a library. Each thingy (function, library,
package etc.) should do one thing, and only one thing, well.
Sometimes called the Single Responsibility Principle (SRP).

You should be able to express your application's logic
without having dynamic memory allocation entangled in it.

<snip>

--
Nick Keighley

"Beware of bugs in the above code; I have only proved it correct, not
tried it."
-- Donald Knuth
 
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.
...SNIP...


I ran this program and gave it some weired inputs and I get some
strange problems:


Ctrl + 4 --> programs says "Quit"
Ctrl + 2 --> program exits saying word_count is zero.

with other numbers it does not print anything on the screen but recognizes
that a word was entered. See the output for "Ctrl + 3" and "Ctrl + 5":

[arnuld@dune ztest]$ ./a.out
^[
You entered: [- containing 1 alphabets
word count = 1

[arnuld@dune ztest]$ ./a.out
^]
You entered: [] - containing 1 alphabets
word count = 1
[arnuld@dune ztest]$


Whats happening to the program ?
 
A

arnuld

...SANIP...
It's also important to note that 'z' is not supported by all
implementations. For greater portability, you can use "%lu" with a
cast to unsigned long:

printf("sizeof whatever = %lu\n", (unsigned long)sizeof whatever);

Note that if size_t has a wider range than unsigned long, then this
could produce incorrect output if "sizeof whatever" happens to exceed
ULONG_MAX.


Well, If 'z' not there in C90, and if we use then could be problems
caused by conversion of size_t to unsigned long then I think I better stop
using size_t for all. If I am going to cast it, then why use size_t in
first place ?
 
I

Ian Collins

arnuld said:
Well, If 'z' not there in C90, and if we use then could be problems
caused by conversion of size_t to unsigned long then I think I better stop
using size_t for all.

You can't, size_t is the type of sizeof.
 
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.
... SNIP....


Okay guys, I have finally reduced the get_single_word() to less than 40
lines. Does anyone has his views on my refactoring method:


/* * 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.1
*
*/


#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 save_single_word( char**, char**, unsigned long*);
int allocate_new_mem( char**, char**, unsigned long* );


int main( void )
{
char* pword = NULL;
unsigned long letter_count = 0;
unsigned long word_count = 0;

while( (GSW_OK == get_single_word(&pword, &letter_count)) && ( *pword != 0) )
{
printf("You entered: [%s] - containing %lu alphabets\n", pword, letter_count);
++word_count;
free( pword );
}

printf("word count = %lu\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 long ele_num = 0;
int ch = EOF;
unsigned long 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;
}

if( save_single_word( ppc, &word_begin, &ele_num ) )
{
return GSW_ENOMEM;
}


*word_begin = '\0';
*Lcnt = ele_num;

return GSW_OK;
}



int save_single_word( char** location_curr, char** location_begin, unsigned long* pul )
{
char ch = EOF;
unsigned long word_length = WORD_SIZE;


while( (EOF != (ch = getchar())) && (! isspace(ch)) )
{
if( (word_length - 1) == (*pul)++ )
{
if( allocate_new_mem( location_curr, location_begin, &word_length ) )
{
return GSW_ENOMEM;
}
}

**location_begin = ch;
++*location_begin;
}

return GSW_OK;
}



int allocate_new_mem( char** moving_p, char** begin_p, unsigned long* 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;
}
 
J

James Kuyper

arnuld said:
I will use C++ then. Don't get angry but I *have* to use C here. I am
doing Socket Programming + whole lot of other communication Techie things
that I am fixed on C most of the times. The actual cause is related with
my job responsibility, not with the language itself.

Actually, if there's a lot of string handling involved, I'd recommend
perl, not C++. Both languages have all of the same capabilities for
doing socket programming that C does. As an interpreted language, perl
is less efficient than either C or C++, but if you have a lot of string
handling in your program, and have sufficiently lax speed requirements,
perl might be the better choice.
 
J

James Kuyper

arnuld said:
I will use C++ then. Don't get angry but I *have* to use C here. I am
doing Socket Programming + whole lot of other communication Techie things
that I am fixed on C most of the times. The actual cause is related with
my job responsibility, not with the language itself.

Actually, if there's a lot of string handling involved, I'd recommend
perl, not C++. Both languages have all of the same capabilities for
doing socket programming that C does. As an interpreted language, perl
is less efficient than either C or C++, but if you have a lot of string
handling in your program, and have sufficiently lax speed requirements,
perl might be the better choice.
 
J

James Kuyper

arnuld said:
:D

So what to do ? Run the risk of incorrectness in casting it to unsigned
long ?

For C90, casting the value of a size_t variable to unsigned long, and
printing it with %lu, will always be correct; size_t was not allowed to
be a type that could hold values bigger than ULONG_MAX. For C99, no cast
is needed, and you can print with %zu. There's no perfect solution that
will work in all possible cases with both versions of C.

However, the C90 solution will only fail in C99 if the value you need to
print is larger than ULONG_MAX; if you can rule out that possibility,
there's nothing wrong with using the C90 solution in C99 code. You're
using an unsigned long for the letter_count, and a size_t for the
word_count. You couldn't possibly have word_count > ULONG_MAX unless
letter_count is also incorrect due to unsigned roll-over.

I see no reason why word_count should have the type size_t. It is not
calculated from any expression which has a type of size_t, and it isn't
passed to any function which requires a size_t argument. It seems more
appropriate to use unsigned long for this purpose.
 
M

Michael

arnuld said:
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.
...SNIP...


I ran this program and gave it some weired inputs and I get some
strange problems:


Ctrl + 4 --> programs says "Quit"
Ctrl + 2 --> program exits saying word_count is zero.

with other numbers it does not print anything on the screen but recognizes
that a word was entered. See the output for "Ctrl + 3" and "Ctrl + 5":

[arnuld@dune ztest]$ ./a.out
^[
You entered: [- containing 1 alphabets
word count = 1

[arnuld@dune ztest]$ ./a.out
^]
You entered: [] - containing 1 alphabets
word count = 1
[arnuld@dune ztest]$


Whats happening to the program ?
In gnome-terminal:
Ctrl-2 is ^@ 0x00 (NUL, Null)
Ctrl-3 is ^[ 0x1b (ESC, Escape)
Ctrl-4 is ^\ 0x1c (FS, File seperator)
Ctrl-5 is ^] 0x1d (GS, Group seperator)
Ctrl-6 is ^^ 0x1e (RS, Record seperator)
Ctrl-7 is ^_ 0x1f (US, Unit seperator)
 
B

Ben Bacarisse

arnuld said:
Oh.. no, I wonder why the program did not crash wit this bug.

because (at least in part) the code is executed only when realloc
fails and you probably have to take special action to test that code
path.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top