user25976 user25976 - 2 months ago 11
C Question

C - converting a uppercase char to lowercase char

How can I convert these characters to lowercase? Using tolower() is not working.

I have an array like this:

static char clef[][7] =
{
['A'] = "X",
['B'] = "Y",
['C'] = "Z",
['D'] = "A",
['E'] = "B",
['F'] = "C",
['G'] = "D",
['H'] = "E",
['I'] = "F",
['J'] = "G",
['K'] = "H",
['L'] = "I",
['M'] = "J",
['N'] = "K",
['O'] = "L",
['P'] = "M",
['Q'] = "N",
['R'] = "O",
['S'] = "P",
['T'] = "Q",
['U'] = "R",
['V'] = "S",
['W'] = "T",
['X'] = "U",
['Y'] = "V",
['Z'] = "W"

};


This code is intended to replace letters in a text based on a shift in the key array above. The new text is all in uppercase. I would like to make them lower case except in cases that follow the '.' marking the beginning of a new sentence.

static void crack(FILE *fp, const char *buffer, const char *pad1, const char *pad2, int shift_index)
{
int c;
char d;
const char *pad = pad1;
int col = 0;

idx = shift_index - 4;

for (int i = 0; (c = buffer[i]) != '\0'; i++)
{
if (col == 0)
{
fputs(pad, fp);
col += strlen(pad);
pad = pad2;
}

col++;
c = toupper(c);

printf("C :: %d", c);

if (c < MAX_CLEF && clef[c][0] != '\0')
{

/*fputs(clef[c - idx], fp);
printf("Value : %s", clef[c-idx]);*/


if (buffer[i - 1] == '.') {
fputs(clef[c - idx], fp);
}
else {
fputs(tolower(clef[c-idx]), fp);
}

col += strlen(clef[c - idx]);
}
else
{
putc(c, fp);
col++;

printf("C :: right here %d", c);
}
if (col > 72)
{
putc('\n', fp);
col = 0;
}


}

}


I'm getting some warnings when compiling however:

incompatible pointer to integer conversion passing 'char [7]' to parameter
of type 'int' [-Wint-conversion]
fputs(tolower(clef[c-idx]), fp);


and

incompatible integer to pointer conversion passing 'int' to parameter of
type 'const char *' [-Wint-conversion]
fputs(tolower(clef[c-idx]), fp);

Answer

"A" is a string.

'A' is a character.

Thus you are feeding tolower() with a string, so change this:

fputs(tolower(clef[c-idx]), fp);

to this:

fputc(tolower(clef[c-idx][0]), fp);

As Dimitri said, you want to use fputc(), not fputs() which is good for strings..

As Keith Thompson stated: tolower() has undefined behavior if the argument is negative and not equal to EOF. To convert a char argument, you need to convert it to unsigned char.

Minimal example:

#include <stdio.h>
#include <ctype.h>
int main (void)
{
    char clef[][2] =
    {
        ['A'] = "X",
    };

    printf("Uppercase = %s\n", clef['A']);
    printf("Lowercase = %c\n", tolower((unsigned char)clef['A'][0]));

    // or equivalently, as BLUEPIXY stated
    printf("Lowercase = %c\n", tolower((unsigned char)(*clef['A'])));    

    return 0;
}

Output:

C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c 
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out 
Uppercase = X
Lowercase = x
Lowercase = x