Home > Back-end >  create new converted string from "toupper()" in c
create new converted string from "toupper()" in c

Time:12-16

Trying to take a lower case string, and create a new string after making characters uppercase

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

int main (void)
{
    string word = "science";
    char new_word[] = {};

    for (int i = 0, len = strlen(word); i < len; i  )
    {
        if (islower(word[i]))
        {
            new_word = new_word   toupper(word[i]);
        }
    }
}

I am getting "error: array type 'char[0]' is not assignable".

This isn't all, and I am sure with my full program there might be an easier way, but I built out everything else, and the only point that I am struggling with is looping through my string to get a new word that is uppercase.

Any assistance would be greatly appreciated!

CodePudding user response:

char new_word[] = {};

Your new char array has length 0 and any access invokes undefined behaviour (UB) as you access it outside its bounds.

If your compiler supports VLAs:

    string word = "science";
    char new_word[strlen(word)   1] = {0,};

if not:


    string word = "science";
    char *new_word = calloc(1, strlen(word)   1);

and

new_word[i] = toupper((unsigned char)word[i]);

If you used calloc do not forget to free the allocated memory

CodePudding user response:

Undefined behavior when word[i] < 0

Avoid that by accessing the string as unsigned char

As per C reference about toupper()

int toupper( int ch );

ch - character to be converted. If the value of ch is not representable as >unsigned char and does not equal EOF, the behavior is undefined.

This is not correct, compiler gives error , "error: assignment to expression with array type"

new_word = new_word   toupper(word[i]);

which is not allowed with an array type as LHS of assignment. changed to new_word[i] = toupper((unsigned char)word[i]);

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

int main (void)
{
    char word[] = "science";
    char new_word[sizeof word] = ""; 
    int i;

    for (i = 0; i < sizeof(word); i  )
    {
        if (islower(word[i]))
        {
            new_word[i] = toupper(word[i]);
        }
        else    /* for Upper case latter, simply fill the array */
        {
            new_word[i] = word[i];
        }
    }
    new_word[i] = '\0';
    printf("%s", new_word);
}

OUTPUT: SCIENCE

EDIT: Just echo comment from solution given by M.M and comment from David C. Rankin casting is not necessary for this example. read comment below from M.M and David C. Rankin Removed unsigned char from islower() and toupper()

CodePudding user response:

This is but one way of accomplishing the task. Make sure to come up with your way of doing.

    #include <stdio.h>
    #include <string.h>
    #define MAX_BUFF 128   
    
    char *upperCase(char *c) {
        //printf("%s, %d", c, strlen(c));
        for(int i=0; i<strlen(c) && i<MAX_BUFF; i  ) {
           c[i] = c[i] - ' ';  // convert char to uppercase
           //printf(">> %c", c[i]);
        }
        return c;
     }  
    int main (void)
    {
        char word[MAX_BUFF] = "science";
        char new_word[MAX_BUFF];
        
         printf("in>> %s \n", word);
         strcpy(new_word, upperCase(&word[0]));
         printf("out>> %s\n", new_word);
    }

Output:
in>> science 
out>> SCIENCE

CodePudding user response:

Named arrays cannot be resized in C, you have to set the size correctly to start:

size_t len = strlen(word);
char new_word[len   1];   // leaving room for null-terminator

Note that no initializer can be used for new_word when its size was determined by a function call (a lame rule but it is what it is); and you can take out the len loop variable since it is now defined earlier.

Then set each character in place:

new_word[i] = toupper(word[i]);

but be careful with the surrounding if statement: if that were false, then you need to set new_word[i] = word[i] instead.

(Pro tip, you can get rid of the if entirely, because toupper is defined to have no effect if the character was not lower case).

Lastly, there should be a null terminator at the end:

new_word[len] = 0;

NB. To be technically correct, the call to toupper should be: toupper((unsigned char)word[i]) -- check the documentation of toupper to understand more about this.

  • Related