user979033
user979033

Reputation: 6460

C language: change user input

I need to write program that get Input from user and in case i have quate (") i need to change all the chars inside the quotes to uppercase.

int main()
{
    int quoteflag = 0;
    int ch = 0;
    int i = 0;
    char str[127] = { '\0' };

    while ((ch = getchar()) != EOF && !isdigit(ch))
    {
        ++i;
        if (ch == '"')
            quoteflag = !quoteflag;

        if (quoteflag == 0)
            str[i] = tolower(ch);
        else
        {
            strncat(str, &ch, 1);
            while ((ch = getchar()) != '\"')
            {
                char c = toupper(ch);
                strncat(str, &c, 1);
            }

            strncat(str, &ch, 1);
            quoteflag = !quoteflag;
        }

        if (ch == '.')
        {
            strncat(str, &ch, 1);
            addnewline(str);
            addnewline(str);
        }
        else
        {
            if ((isupper(ch) && !quoteflag))
            {
                char c = tolower(ch);
                strncat(str, &c, 1);
            }
        }
    }

    printf("\n-----------------------------");
    printf("\nYour output:\n%s", str);
    getchar();

    return 1;
}

void addnewline(char *c)
{
    char tmp[1] = { '\n' };
    strncat(c, tmp, 1);
}

So my problem here is in case my input is "a" this print at the end "A instead of "A" and i dont know why

Upvotes: 0

Views: 437

Answers (2)

cegfault
cegfault

Reputation: 6632

The problem is that you are using strncat in a weird way. First, strncat will always do nothing on big-endian systems. What strncat does is read the inputs ... as strings. So passing and int (four or eight bytes) into the function, it'll read the first byte. If the first byte is 0, then it'll believe it is the end of the string and will not add anything to str. On little endian systems, the first byte should be the char you want, but on big-endian systems it will be the upper byte (which for an int that holds a value less than 255, will always be zero). You can read more about endianness here.

I don't know why you're using strncat for appending a single character, though. You have the right idea with str[i] = tolower(ch). I changed int ch to char ch and then went through and replaced strncat(...) with str[i++] = ... in your code, and it compiled fine and returned the "A" output you wanted. The source code for that is below.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    int quoteflag = 0;
    char ch = 0;
    int i = 0;
    char str[127] = { '\0' };

    while ((ch = getchar()) != EOF && !isdigit(ch))
    {
        if (ch == '"')
            quoteflag = !quoteflag;

        if (quoteflag == 0)
            str[i++] = tolower(ch);
        else
        {
            str[i++] = ch;
            while ((ch = getchar()) != '\"')
            {
                char c = toupper(ch);
                str[i++] = c;
            }
            str[i++] = ch;
            quoteflag = !quoteflag;
        }

        if (ch == '.')
        {
             str[i++] = '.';
             str[i++] = '\n';
             str[i++] = '\n';
        }
        else
        {
            if ((isupper(ch) && !quoteflag))
            {
                char c = tolower(ch);
                str[i++] = c;
            }
        }
    }

    printf("\n-----------------------------");
    printf("\nYour output:\n%s", str);
    getchar();

    return 1;
}

Upvotes: 1

Ken Y-N
Ken Y-N

Reputation: 15009

You should delete the ++i; line, then change:

str[i] = tolower(ch);

To:

str[i++] = tolower(ch);

Otherwise, since you pre-increment, if your first character is not a " but say a, your string will be \0a\0\0.... This leads us on to the next problem:

strncat(str, &ch, 1);

If the input is a", then strncat(str, &'"', 1); will give a result of \"\0\0... as strncat will see str as an empty string. Replace all occurrences with the above:

str[i++] = toupper(ch);

(The strncat() may also be technically undefined behaviour as you are passing in an malformed string, but that's one for the language lawyers)

This will keep track of the index, otherwise once out of the quote loop, your first str[i] = tolower(ch); will start overwriting everything in quotes.

Upvotes: 0

Related Questions