Home > database >  Issue while taking a series of character as input and converting the case in C
Issue while taking a series of character as input and converting the case in C

Time:12-25

Hey I am beginner in programming i need help to solve this problem. I am writing a code to input a character and convert it into the opposite case (if it is in lower case then convert to upper case and vice-versa), the code is supposed to terminate when user enters semicolon (;).

#include<stdio.h>
int main(int argc, char const *argv[])
{
    /* code */
    char c;
    while(1)
    {
        c=getchar();
        if(c<97)
        {
            printf("%c",c 32);
        }
        if(c>=97)
        {
            printf("%c",c-32);
        }
        if(c == ';')
        {
            break;
        }
    }
    return 0;
}

Output which i am getting:

t
T*
*H
h*
*j
J*
*;
[

Issue - After entering the first character, when i press enter it gets converted into upper case which is fine, but i am also getting an asterisk (*). Again to input next character , when i am pressing enter i am getting *. Also, when i am pressing ; the program do terminates but it prints "[" . Can you please help me with this, not sure about why the * and [ are coming in the O/P.

Expected output:

t
T
H
h
j
J
;

CodePudding user response:

There are a few issues with your code.

  1. You should check for termination ; before you convert the character.
  2. You should not hard-code ASCII values; instead use 'a', 'z', 'A', 'Z', etc..
  3. You should check both upper and lower bounds. This will prevent you from trying to convert the \n (newline) character (which is where the * comes from: ASCII code for \n is 10, for * is 42).

CodePudding user response:

The reason of getting * character in output is that after entering a character you must be pressing ENTER key, that means, there are two characters in input buffer - the character you have entered followed by \n character. The character you have entered is converted to opposite case and printed and when getchar() is called again it read \n character from input buffer.

The decimal ascii value of \n character is 10. The if condition (c<97) evaluate to true and 32 is added to 10 which results in 42 which is decimal ascii value of * character. Hence, you are getting * character in output.

When you enter ; character, decimal ASCII of ; is 59, the if condition (c<97) evaluate to true and 32 is added to 59 which results in 91 and ASCII character of decimal value 91 is [. Hence, you are getting [ character when entering ;.

Instead of just checking if(c<97) for upper case, change it to if ((c>=65) && (c<=90)). Same is for lower case character, instead of checking if(c>=97), change it to if ((c>=97) && (c<=122)).

Note that return type of getchar() is int and not char. So, the type of c should be int:

int c;   // changed type from char to int
while(1)
{
    c = getchar();
......

You should also add the check for EOF because getchar() returns EOF on failure. That said, you can have while ((ch = getchar()) != EOF) in place of while(1).

Putting these altogether, you can do:

#include <stdio.h>
#include <stdlib.h>
 
int main (void)
{ 
    int ch;

    while ((ch = getchar()) != EOF) {
        if ((ch >= 65) && (ch <= 90)) {
            printf ("%c\n", ch   32);
        } else if ((ch >= 97) && (ch <= 122)) {
            printf ("%c\n",ch - 32);
        } else if(ch == ';') {
            break;
        }
    }

    /* If loop not terminated due to ';' character 
       then check for EOF and error */
    if (ch != ';') {
        /* Test reason for reaching EOF. */
        if (feof (stdin)) {
            /* if failure caused by end-of-file condition */
            printf ("End of file reached\n");
        } else if (ferror (stdin)) {
            /* if failure caused by some other error */
            perror ("getchar() failed");
            exit (EXIT_FAILURE);
        }
    }

    return 0;
}
  • Related