0

I'm trying to write exercise of the "C Primer Plus" book. In one of them, I faced something that I couldn't solve or figure out what's going on. After step-by-step debugging trials, I just tested this:

    #include <stdio.h>

    int main()
    {
        char str[500];
        gets(str);
        puts(str);

        return 0;
    }

the output (as desired) :

exact ly every thing I enter

exact ly every thing I enter

But about the exercise I'm trying to do, it's sensitive to more than 2 successive spaces. the gets() is just followed by the puts(); but I don't know what's wrong. So I quote the whole code:

/*
BUG: MORE THAN 1 SPACES NEXT TO EACHOTHER. WHERE THE FIRST CHARACTER GOES?!!

Write a function that takes a string as an argument and removes the spaces from the string.
Test it in a program that uses a loop to read lines until you enter an empty line.
The program should apply the function to each input string and display the result.
*/

#include <stdio.h>
#include <string.h>

int spaceRemover(char *in);
void takeBack(char *in);

int main(void)
{
    puts("Enter a string for the SPACE-REMOVER: (RETURN to quit)");
    do
    {
        char str[500];
        int spaces;
        gets(str);
        puts(str); //for debugging to know is it complete just after gets() ?
        //printf("\nFirst char of string: %c\n",str[0]);
        //printf("\nFirst Char: %p '%c'\n",str,*str);
        spaces=spaceRemover(str);
        printf("\n%d spaces removed: \n",spaces);
        puts(str);
        puts("\nEnter a string for the SPACE-REMOVER: (RETURN to quit)");
    }
    while (getchar() != '\n');

    return 0;
}

int spaceRemover(char *in)
{
    int count=0, i;
    for (i=0 ; i<strlen(in) ; i++)
        while ( *(in+i)==' ' )      //IF will skip more than one space; but WHILE won't
        {
            //printf("%p '%c' \t B4: %p '%c'\n",in+i,*(in+i),in+i-1,*(in+i-1));
            takeBack(in+i);
            count++;

        }
    return count;
}

void takeBack(char *spaceLocation)
{
    int j=0;
    while (*(spaceLocation+j)!= '\0' )
    {
        *(spaceLocation+j) = *(spaceLocation+j+1);
        //putchar(*(spaceLocation+j+1));
        j++;
    }

    return;
}

the output:

Enter a string for the SPACE-REMOVER: (RETURN to quit)

this is separated by single spaces

this is separated by single spaces


5 spaces removed: 

thisisseparatedbysinglespaces


Enter a string for the SPACE-REMOVER: (RETURN to quit)

I'll    try   more than   single space separators

'll    try   more than   single space separators

13 spaces removed: 

'lltrymorethansinglespaceseparators

NOTE: using the Blockquote with this one, discards the successive spaces.

what's going on here? is there anything wrong with my code, causing this?

(using Code::Blocks with gcc.)

pedyram
  • 330
  • 1
  • 2
  • 11

2 Answers2

1

Where the first character of the string goes?

Your first character is read by getchar in while (getchar() != '\n');. When you entered the string

I'll    try   more than   single space separators  

then first character I is read by getchar and compared to \n. Therefore, leaving behind only

'll    try   more than   single space separators    

in the input buffer to read by gets. Change the main body to:

    char str[500];
    puts("Enter a string for the SPACE-REMOVER: (RETURN to quit)");
    gets(str);
    do
    {
        int spaces;
        puts(str); //for debugging to know is it complete just after gets() ?
        //printf("\nFirst char of string: %c\n",str[0]);
        //printf("\nFirst Char: %p '%c'\n",str,*str);
        spaces=spaceRemover(str);
        printf("\n%d spaces removed: \n",spaces);
        puts(str);
        puts("\nEnter a string for the SPACE-REMOVER: (RETURN to quit)");
        gets(str);
    }
    while (str[0]);
haccks
  • 104,019
  • 25
  • 176
  • 264
1

So the problem is with your loop's exit condition i.e. when you say

puts("\nEnter a string for the SPACE-REMOVER: (RETURN to quit)");

inside the loop and starts entering the string, your getchar() starts expecting character from stdin which is supplied by the first character of your string. Therefore in next iteration str is without its first character not what you expected it to be.

So to make your code working as per the requirements

i.e.

Input strings until a blank string is not entered.

PRO TIP: Don't use gets, its a dangerous routine. Use fgets instead. Read more here

Change your loop in main routine to this.

do
    {
        int spaces;
        //for debugging to know is it complete just after gets() ?
        //printf("\nFirst char of string: %c\n",str[0]);
        //printf("\nFirst Char: %p '%c'\n",str,*str);
        spaces=spaceRemover(str);
        printf("\n%d spaces removed: \n",spaces);
        puts(str);

        puts("\nEnter a string for the SPACE-REMOVER: (RETURN to quit)");
        gets(str);
        puts(str);
    }
    while (strcmp(str,""));
Community
  • 1
  • 1
anurag-jain
  • 1,380
  • 2
  • 11
  • 31