2

I'm on Win10, currently learning C, and I quite don't understand my output (EKEKEKEKE) for a simple exercice that ask for an input and give as output the same string without vowels.

inputBLABLABLA
EKEKEKE
outputB.L.B.L.B.L.
inputBLABLABLA
outputK.K.K.
int main()
{
    for (int i = 0; i < 2; i = i + 1)
    {

        printf("input");
        char titre[101] = {0};
        scanf("%[^\n]\n", titre);


        int j = 0;
        char t = titre[0];

        printf("output");

        while ((t != '\0') && (j < 101))
        {
            if ((t != 'A')
                && (t != 'E')
                && (t != 'I')
                && (t != 'O')
                && (t != 'U')
                && (t != 'Y')
                && (t != ' '))
            {
                printf("%c.", t);
            }
            j = j + 1;
            t = titre[j];
        }
        if (i == 0)
        {
            printf("\n");
        }
    }
}

Solken
  • 23
  • 5
  • 1
    I never use `scanf` with trailing whitespace specs so I can't explain *why* it misbehaves, but if you change it to `scanf(" %[^\n]", titre);` that should be better. Notice the space in front of `%` which filters any previous newline, spaces etc. which were left in the input buffer. – Weather Vane Nov 29 '20 at 17:27
  • 1
    You should never use `scanf` at all (see https://stackoverflow.com/questions/58403537/what-can-i-use-for-input-conversion-instead-of-scanf and https://stackoverflow.com/questions/15664664/scanf-regex-c/15664816#15664816 for why). Read user input a line at a time with `fgets` (or `getline` if available). – zwol Nov 29 '20 at 17:40

2 Answers2

1

Well, the problem is really with the scanf() regular expression. Mainly that you're eating all characters except the newline, until you hit a newline. However, after matching all that scanf() still doesn't return because it is still 'matching' more. By changing that expression so that am not matching a newline but an arbitrary character (which should be a newline), I'm able to get it to respond as you expect. I've also modified your code slightly to move some functionality to another function:


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

#define INPUT_COUNT  2
#define BUFFER_SIZE  100

int is_vowel (char c)
{
    const char *vowels = "AEIOUY ";
    for (const char *s = vowels; *s != '\0'; s++) {
        if (toupper(c) == *s) {
            return 1;
        }
    }
    return 0;
}

int main ()
{
    for (int i = 0; i < INPUT_COUNT; i++) {
        char c, titre[BUFFER_SIZE + 1] = {0};

        // Scan in a line.
        printf("Input:\t");
      
        // %100 <- Limit 100 characters. %c <- Trick to get around newline issue
        scanf(" %100[^\n]%c", titre, &c);

        printf("Output:\t");
        for (int j = 0; j < BUFFER_SIZE && titre[j] != '\0'; j++) {

            if (!is_vowel(titre[j])) {
                printf("%c.", titre[j]);
            }
        }
        putchar('\n');
    }
}
Micrified
  • 3,338
  • 4
  • 33
  • 59
0

You chould use gets to read a string like this :

int main()
{
    for (int i = 0; i < 2; i = i + 1)
   {
       printf("input :");
       char titre[101] = {0};
       gets(titre);
       int j = 0;
       char t = titre[0];
       printf("output :");

       while ((t != '\0') && (j < 101))
       {
          if ((t != 'A')&&(t != 'E')&&(t != 'I')&&(t != 'O')&&(t != 'U')&&(t != 'Y')&&(t != ' '))
          {
              printf("%c.", t);
          }
           j = j + 1;
           t = titre[j];
       }
       if (i == 0)
       {
           printf("\n");
       }
    }
  }
MED LDN
  • 684
  • 1
  • 5
  • 10
  • 4
    Never use or recommend `gets`, it is no longer part of the standard C library. Please read [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – Weather Vane Nov 29 '20 at 17:53
  • 1
    @WeatherVane If you're going to bring that up, you should also point out that `scanf("%[...]")`, with no field width, as seen in OP's code, is every bit as dangerous as `gets`, and for the same reason. – zwol Nov 29 '20 at 17:59
  • @zwol yes and overlooked in my earlier comment. – Weather Vane Nov 29 '20 at 18:00
  • @WeatherVane Sorry .So, how do I read a string – MED LDN Nov 29 '20 at 18:02
  • Please use `fgets()`. But unlike `gets()` it retains the newline. – Weather Vane Nov 29 '20 at 18:06
  • 1
    @MEDLDN `getline` if possible, `fgets` otherwise. (The difference is that `getline` uses a `malloc`ed buffer and therefore imposes no limit in the length of the line. However, it's not in ISO C, whereas `fgets` is.) – zwol Nov 29 '20 at 18:06