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

void even(char *p, int l, char *q);

int main()
{
    char str2[23];
    char str1[23];
    printf("Enter a sentence\n");
    gets(str1);
    int l = strlen(str1);
    even(str1, l, str2);

    return 0;
}

void even(char *p, int l, char *q)
{
    for (int y = 0; y < l;)
    {
        if (*(p + y) != ' ')
        {
            *(q + y) = *(p + y);
            y++;
        }
        else
        {
            if (*(p + y + 1) == ' ')
            {
                *(q + y) = *(p + y);
                while (*(p + y) == ' ')
                {
                    y++;
                }
            }
        }
    }
    printf("%s", q);
}

This program intends to reduce multiple spaces in the string, entered by the user, to a single space. I am just a beginner in C as well as coding. I don't understand what is wrong with this. My compiler just keeps on taking the input infinitely and doesn't execute anything.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
Kashish
  • 21
  • 4
  • 7
    `gets` is impossible to use safely. That is why it was removed from the language. – William Pursell Feb 13 '21 at 10:55
  • https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used – William Pursell Feb 13 '21 at 10:56
  • 4
    Please indent your code properly. – interjay Feb 13 '21 at 10:57
  • Your indentation is ... leaving much room for improvement. Please embrace a consistent indentation as a helpful debugging and analysis tool. – Yunnosch Feb 13 '21 at 11:13
  • 1
    Welcome to SO. You need to learn to use proper terms to avoid confusion. One important step is to distinguish compilation from execution of your program. Your compiler does not take any input. Your program does. When you run your program, the compiler has already done its job. It is also important to distinguish errors during compilation and during runtime. – Gerhardh Feb 13 '21 at 11:22

1 Answers1

3

There are multiple problems in your code:

  • gets() must no longer be used in C programs, it has been removed from the C Standard as of C11 because it cannot be used safely. You should use fgets() instead and handle the trailing newline explicitly.

  • to remove the redundant spaces when copying the string, you need a separate index into the destination string and the source string.

  • you also need to set a null terminator at the end of the destination string.

  • avoid naming a variable l because it looks confusingly close to 1.

  • you should output the modified string in main() and let even() perform the cleaning without this side-effect.

  • your indentation style is very unusual. Using a more classic style will make the code more readable for the majority of programmers (including yourself).

Here is a modified version:

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

void even(const char *p, int len, char *q);

int main() {
    char str2[80];
    char str1[80];
    printf("Enter a sentence\n");
    if (!fgets(str1, sizeof str1, stdin)) {
        // handle unexpected end of file gracefully
        return 1;
    }
    int len = strlen(str1);
    // strip the trailing newline if any
    if (len > 1 && str1[len - 1] == '\n') {
        // updated len is still the length of the string
        str1[--len] = '\0';
    }
    even(str1, len, str2);
    printf("%s\n", q);
    return 0;
}

void even(const char *p, int len, char *q) {
    int x, y;
    for (x = y = 0; y < len;) {
        *(q + x) = *(p + y);
        x++;
        y++;
        if (*(p + y - 1) == ' ') {
            // skip redundant blanks
            while (*(p + y) == ' ') {
                y++;
            }
        }
    }
    // set the null terminator
    *(q + x) = '\0';
}

Note also that the array syntax is much more readable than explicit pointer arithmetic and dereferencing as above. Here is a simplified version of even():

void even(const char *p, int len, char *q) {
    int x, y;
    for (x = y = 0; y < len;) {
        q[x] = p[y];
        x++;
        y++;
        if (p[y - 1] == ' ') {
            // skip redundant blanks
            while (p[y] == ' ') {
                y++;
            }
        }
    }
    // set the null terminator
    q[x] = '\0';
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189