1

For a school assignment i need to create a program that lets the user input a string that should be stored in an array. Then the program calls a function that removes all the spaces in the array. After that call on a function that makes all letters lowercase. After that call a 3rd function that checks if the current array is a palindrome and return 1 if it is and 0 if not. The program works fine. But after i put a do while around the code that lets you input the array and call the functions it seems to skip the scanf that takes the input into an array, basically the program does not let me input another string to be stored in the array to check if that is a palindrome. Currently i have deleted the do while in my code but i have to have it implemented, can someone help me?

int is_palindrome(char input_string[]);
void delete_spaces(char input_string[]);
void convert_to_lower(char input_string[]);

int main(void)
{
    char str[1000];
    char again;

    do {
        printf("Mata in en sträng: ");

        int i = 0;
        for (i = 0; i < 100; i++)
        {
            scanf("%c", &str[i]);
            if(str[i]=='\n')
            {
                break;
            }
        }

        delete_spaces(str);
        convert_to_lower(str);
        int palindrom_or_nah = is_palindrome(str);

        if(palindrom_or_nah == 1)
            printf("\nSträngen är ett palindrom\n\n");
        else
            printf("\nSträngen är inte ett palindrom\n\n");

            printf("Vill du köra igen? j/n: ");
            scanf(" %c", &again);
    }while(again == 'j');
    return 0;
}

//Kolla ifall strängen är ett palindrom
int is_palindrome(char input_string[])
{
    int answer = 0, i = 0;
    int h = (unsigned)strlen(input_string)-1;

    while(h>1)
    {
        if(input_string[i++] != input_string[h--])
        {
            break;
        }
        else
        {
            answer = 1;
        }
    }
    return answer;
}

//Ta bort mellanslag och andra tecken i strängen
void delete_spaces(char input_string[])
{
    int i = 0, j = 0;
    char rem_space[strlen(input_string)];

    while(input_string[i] != '\0')
    {
        if(input_string[i] != ' ')
        {
            if(isalpha(input_string[i]))
            {
                rem_space[j++] = input_string[i];
            }
        }
        i++;
    }
    rem_space[j] = '\0';

    for(i = 0; i < strlen(input_string); i++)
    {
        input_string[i] = rem_space[i];
    }

}

//Gör alla bokstäver till små bokstäver
void convert_to_lower(char input_string[])
{
    int count = (unsigned)strlen(input_string), i;

    for (i = 0; i < count; i++)
    {
        input_string[i] = tolower(input_string[i]);
    }
}
klutt
  • 30,332
  • 17
  • 55
  • 95
  • 3
    Rather than showing us the code that *does* work, show us the code that *doesn't* work. – dbush Oct 01 '18 at 13:48
  • 3
    can you post the code block with the do-while that is behaving incorrectly? – Katajun Oct 01 '18 at 13:49
  • 1
    I presume you are typing in the whole sentence and then pressing "Enter" once. So please see [scanf() leaves the newline char in the buffer](https://stackoverflow.com/questions/5240789/scanf-leaves-the-new-line-char-in-the-buffer) and that newline is read as the first character in the next session. In which case `if(str[i]=='\n') { break; }` will happen. – Weather Vane Oct 01 '18 at 13:49
  • 2
    After `scanf(" %c", &again);` there is still a `'\n'` in the input stream and therefore it will not read in a second array – Support Ukraine Oct 01 '18 at 13:51
  • I've changed the code with the one that doesn't work. How should i clear the buffer to clear out the \n? – O. Sherlock Oct 01 '18 at 13:53
  • 2
    By using `fgets` instead of messing around with `scanf`. – Weather Vane Oct 01 '18 at 13:54
  • 2
    @O.Sherlock As a quick fix you could add `char tmp = 'a'; while(tmp != '\n') scanf("%c", &tmp);` just after `scanf(" %c", &again);` but as Weather Vane says `fgets` is in many cases better than `scanf` – Support Ukraine Oct 01 '18 at 13:57
  • Ive got it to work now, changed the scanf to gets f as Vane said, and also added this last code, thanks all. – O. Sherlock Oct 01 '18 at 14:01

1 Answers1

0

Inserting a simple printout would give you a good clue. Do like this:

if(str[i]=='\n')
{
    printf("Read the string: %s\n", str);
    break;
}

When I run this code, i get this:

$ ./a.out 
Mata in en sträng: asdf
Read the string: asdf


Strängen är inte ett palindrom

Vill du köra igen? j/n: j
Mata in en sträng: Read the string: 
sdf

Strängen är inte ett palindrom

Vill du köra igen? j/n: j
Mata in en sträng: Read the string: 
df

Strängen är inte ett palindrom

Vill du köra igen? j/n: j
Mata in en sträng: Read the string: 
f

Strängen är inte ett palindrom

Vill du köra igen? j/n: j
Mata in en sträng: Read the string: 


Strängen är inte ett palindrom

Vill du köra igen? j/n: j
Mata in en sträng: Read the string: 


Strängen är inte ett palindrom

Vill du köra igen? j/n: 

The problem is that the input buffer is not emptied. A good way to get around this is to use fgets instead of scanf. scanf is useful when you have data in a well defined format, which user input is not, since users do mistakes. User input is in general best handled by first reading it into a string and parse it afterwards. Here is a way to get it to work:

int main(void)
{
    char str[1000];

    do {
        printf("Mata in en sträng: ");
        int i = 0;

        if(fgets(str, 100, stdin) == NULL) {
            // Handle this error
        }

        delete_spaces(str);
        convert_to_lower(str);
        int palindrom_or_nah = is_palindrome(str);

        if(palindrom_or_nah == 1)
            printf("\nSträngen är ett palindrom\n\n");
        else
            printf("\nSträngen är inte ett palindrom\n\n");

            printf("Vill du köra igen? j/n: ");
            if(fgets(str, 100, stdin) == NULL) {
                // Handle error
            }
    } while(str[0] == 'j');
    return 0;
}

And remember that for both scanf and fgets you should ALWAYS check the return value for errors.

klutt
  • 30,332
  • 17
  • 55
  • 95