Here is the code i have written to accept string from the user.
Can you please modify the code so as it can even count the space as well as print the whole line with the spaces instead of the first word.

Thanks a lot.

#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <conio.h>
int strlength (char input[])
{
 int count = 0;
 while (input[count++] != '\0');
 return count;
}

main ( )
{
 char* s = 0;
 char inputBuffer;
 int index = 0;
 printf("\nEnter the name u want to enter : ");
 while ((inputBuffer = getchar()) != '#') // some termintaing cond.
 {
  s = malloc(sizeof(char));
  s[index] = inputBuffer;
 }
 
 printf("The length of this string is %d", strlength(s));
 printf("\n");
 
}

>>Can you please modify the code so ...

No, I don't do homework for anyone.

>> s = malloc(sizeof(char));
This just allocates one character, causing a 1 byte memory leak on every loop iteration.
>> s[index] = inputBuffer;
Since the malloc allocates only one character, this line will just scribble all over memory and most likely cause your program to crash big-time.

How to fix the above problems: use realloc and pass the number of bytes to allocate
s = realloc(s,index+1);

Tip: sizeof(char) is ALWAYS 1 regardless of computer, operating system, or compiler.

>#include <assert.h>
You haven't used this, so there's no point in including it.

>#include <malloc.h>
stdlib.h is the header you want for malloc.

>#include <conio.h>
You don't use anything from conio, so why kill your program's portability?

>main ( )
The correct definition for main is int main ( void ) .

>while (input[count++] != '\0');
This will never return 0, even for an empty string. Is that what you want?

>s = malloc(sizeof(char));
This is your single biggest problem. It's a memory leak, and you don't allocate enough memory.

>s[index] = inputBuffer;
This is a guaranteed buffer overflow.

>printf("The length of this string is %d", strlength(s));
This is a guaranteed buffer overflow because you don't terminate the string with '\0'.

>}
main returns an int, even when it's implicitly defined. That means you must return a value or invoke undefined behavior.

#include <stdio.h>
#include <stdlib.h>

int strlength ( char input[] )
{
  int count = 0;

  while ( input[count] != '\0' )
    ++count;

  return count;
}

int main ( void )
{
  char* s = 0;
  char inputBuffer;
  int index = 0;

  printf ( "Enter the name u want to enter: " );
  fflush ( stdout );

  while ( ( inputBuffer = getchar() ) != '\n' )
  {
    char *temp = realloc ( s, index + 2 );

    if ( temp == 0 )
    {
      fputs ( "Memory allocation error", stderr );
      break;
    }

    s[index++] = inputBuffer;
  }

  s[index] = '\0';

  puts ( s );
  printf ( "The length of this string is %d\n", strlength ( s ) );

  return 0;
}

Why don't you use s[256] so you don't need malloc. Use gets for string input. To calculate spaces (if I understood your task) just iterate the input string example: if (s[index++] == 0x20) numSpaces++;

>Why don't you use s[256] so you don't need malloc.
Why 256? That's the problem with using an array, the size is almost always completely arbitrary. This imposes an unnecessary limit on the program.

>Use gets for string input.
Any credibility you might have had with this post was destroyed when you mentioned gets without first preceding it with "NEVER USE".

>if (s[index++] == 0x20) numSpaces++;
Okay, and now your code doesn't quite work on a machine that uses EBCDIC instead of ASCII. C offers you character constants to avoid such a problem:

if (s[index++] == ' ') numSpaces++;

>Why 256?

I thought its easier that way, no need for malloc or realoc.

>That's the problem with using an array, the size is almost always completely arbitrary. This imposes an >unnecessary limit on the program.

I know that, but after all its only a homework

>Use gets for string input.
>Any credibility you might have had with this post was destroyed when you mentioned gets without first >preceding it with "NEVER USE".

I admit never used string input from user in my life (maybe in school only) so I don't know whats the problem with gets, but if U say so I belive you. Sorry to misled the young student. Use fgets.

>if (s[index++] == 0x20) numSpaces++;
>Okay, and now your code doesn't quite work on a machine that uses EBCDIC instead of ASCII. C offers you >character constants to avoid such a problem:

if (s[index++] == ' ') numSpaces++;

agree with this :)

Thanks a lot for all your help but let me get one thing straight.

No, I don't do homework for anyone.

Friend, neither do i approve of the person who does it. By saying that can you write a code i meant that couldsomeone help me write a code.

I know that, but after all its only a homework

No friend this is not a homework and i never did mention so, this is just a program i have written to improve my understanding.

>> s = malloc(sizeof(char));
This just allocates one character, causing a 1 byte memory leak on every loop iteration.
>> s[index] = inputBuffer;
Since the malloc allocates only one character, this line will just scribble all over memory and most likely cause your program to crash big-time.

@AncientDragon

Can you please explain the meaning of memory leak on each iterationand the scribbling on the memory. I am totally new to such memory concepts and i have run the prog and it is giving the correct output no junk value so how do we know that it is scribbling.


@Miss Narue

>printf("The length of this string is %d", strlength(s));
This is a guaranteed buffer overflow because you don't terminate the string with '\0'.

using printf this way causes buffer overflow ???

But i have modifed the prog a bit and its workin for strings.

int main ( )
{
 char* s = 0;
 char inputBuffer, prevBuffer;
 int index = 0;
 printf("\nEnter the name u want to enter : ");
 while ((inputBuffer = getchar()) != '#')
 {
  s = malloc(sizeof(char));
  s[index++] = inputBuffer;
  prevBuffer = inputBuffer;
 }
 
 printf("The length from main (including null) is %d", index);
 printf("\nThe length from function (including null) is %d", strlength(s, prevBuffer));
 printf("\n");
 return 0;
 
}

Thanks to all and sorry if i said somthing bad.

>I thought its easier that way, no need for malloc or realoc.
Yes, it is easier. The code is shorter, faster, and easier to debug. But if I asked a question that clearly wanted to use dynamic allocation and you told me to use an array, I'd be tempted to smack you.

>I know that, but after all its only a homework
How do you know that the homework doesn't require dynamic allocation?

>I admit never used string input from user in my life
It doesn't have to be user input, you can just as easily redirect from a file and the problems are still there.

>so I don't know whats the problem with gets
What if a line is longer than the buffer that you pass to gets?

>using printf this way causes buffer overflow ???
No, using strlength that way causes buffer overflow. In strlen, this is your loop:

while ( input[count] != '\0' )

If the first character in the string is '\0' then there's not a problem, but because it's extremely difficult and unlikely for a user to actually have getchar return 0, that first character will not be '\0' unless you explicitly set it as such, which you don't. Therefore, the loop will walk all over memory that you don't own, and that's a buffer overflow.

>But i have modifed the prog a bit and its workin for strings.
Just because it works doesn't mean it's correct. Your modified program has all of the same problems we've already pointed out to you. I suggest you try to understand what's going on rather than just change code until it appears to work.

>>meaning of memory leak
it occurs when you use one of the functions that allocate memory, such as malloc() then do not free the memory before using the pointer again. In the code you posted, pointer variable s was allocated over and over without ever freeing the memory. You should have called realloc() instead of malloc() so that the memory block would have been expanded.

>>scribbling on the memory
that means the program is writing outside the allocated memory, and it is not know where the program will write the data, could be almost anywhere. In the code you posted, the program could very easly be writing into other variable's memory address, destroying whatever value was legatimately there. Its something like giving a little kid a crayola and a color book -- watch the child scribble all over the page not paying any attention at all to the lines that define the picture. That's what your program was doing.

>>meaning of memory leak
it occurs when you use one of the functions that allocate memory, such as malloc() then do not free the memory before using the pointer again. In the code you posted, pointer variable s was allocated over and over without ever freeing the memory. You should have called realloc() instead of malloc() so that the memory block would have been expanded.

But when we end the program the memory is automatically returned to the OS for its use and the prog in the end uses the same mem. it was about to use so why the realloc instead of malloc.

Even then i have heeded your advices and rewritten the code.
I even read the tutorials concering the disadvantages of scanf and gets and also flushed the stream buffer before takin input.

It compiles welll but jumps out during execution ie runtime error. The updated code is as follows :

#include <stdio.h>
#include <stdlib.h>

// function for evaluating string length

int strlength ( char input[] )
{
  int count = 0;
  while ( input[count] != '\0' )
    ++count;
  return count;
}

int main(void)
{
  int ch, index = 0;
  char *input = 0;
  char inputBuffer;
 
 // procedure for bypassing the junk in stream
  
  while ((ch = getchar()) != '\n' && ch != EOF);
  fputs ("Enter some text: ", stdout);
  while ((inputBuffer = getchar()) != '/n')
  {
 
   //reallocating taking in consideration the '\0'

   char* input = (char*) realloc (input, index + 2); 

   if (input == NULL) // mem alloc failed
   {
    fputs("Memory allocation error", stderr);
    exit(1);
   }
   else
   {
   input[index++] = inputBuffer; // this is the line bothering me
   }
  }

  input[index] = '\0';
  printf("The length of the string is %d", strlength(input));
  return 0;
}

Hope my third attempt of coding is better than the prev two.
Thanks for always evaluating my code.
Thanks to all for help.

>>But when we end the program the memory is automatically returned to the OS for its use

Not necessarily. Some operating systems do not do that. There are some resources even in MS-Windows that will be permanently lost until the next reboot of the computer if the program that allocated them failes to free them.

>> it was about to use so why the realloc instead of malloc.
I already mentioned that realloc() expands existing memory, malloc() does not. If your program runs long enough it will eventually run out of memory and malloc() will return a NULL pointer.

>> while ((inputBuffer = getchar()) != '/n')

The '/n' should be '\n'

>> char *input = (char*) realloc (input, index + 2);
remove the 'char *' -- it is hiding the other variable
input = (char*) realloc (input, index + 2);

Yes its working thanks a lot to all the guys at the forum.

>> remove the 'char *' -- it is hiding the other variable
Just wanted to know wat is the meanig of this stmt

I thought that i would post the working and clean code so that someone can refer to this for learing the string legth funcitons.

#include <stdio.h>
#include <stdlib.h>
 
int strlength ( char input[] )
{
  int count = 0;
  while ( input[count] != '\0' )
    ++count;
  return count;
}
 
int main(void)
{
  int ch, index = 0;
  char *input = 0;
  char inputBuffer;
 
  while ((ch = getchar()) != '\n' && ch != EOF);
  fputs ("Enter some text: ", stdout);
  while ((inputBuffer = getchar()) != '\n')
  {
   input = (char*) realloc (input, index + 2);
   if (input == NULL)
   {
    fputs("Memory allocation error", stderr);
    exit(1);
   }
   else
   {
 
   input[index++] = inputBuffer;
   }
  }
  input[index] = '\0';
  printf("The length of the string is %d", strlen(input));
  return 0;
}

Thanks again Narue and Dragon.

>>Just wanted to know wat is the meanig of this stmt
it means that you coded two variables using the same name, when you do that only the variable closest to the satatement in which it is used will be visible to the program. Look up the term scope for a more in-depth explaination. You correctly changed your program in your last post to fix that problem.

>> for learing the string legth funcitons.

Most programs use standard C strlen() function that is in string.h -- the only reason to code your own function is for educational purposes. Most real programs do not do that.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.