0

I'm trying to convert a C-String to all lower case wihout the use of tolower from ctype.h . Hower my code does not seem to work: I'm receiving a runtime error. What I'm trying to do is changing the ASCII value of the capitalized letters bij 'a' - 'A' which should convert those values to the ones for lower case as far as I'm aware.

#include <stdio.h>
void to_lower(char* k) {
    char * temp = k;
    while(*temp != 0) {
        if(*temp > 'A' && *temp < 'Z') {
            *temp += ('a' - 'A');
        }
        temp++;
    }
}

int main() {
    char * s = "ThiS Is AN eXaMpLe";
    to_lower(s);
    printf("%s",s);
}
Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
Actaeonis
  • 149
  • 1
  • 13

3 Answers3

9

Two errors.

This code won't convert A and Z to lowercase :

if(*temp > 'A' && *temp < 'Z') {

Use >= and <= instead.

And it's not legal to try to modify a string literal ! Arrays can be modified, string literals can't.

Change that char * s = "ThiS Is AN eXaMpLe"; to char s[] = "ThiS Is AN eXaMpLe";

tux3
  • 7,171
  • 6
  • 39
  • 51
  • The contents of an array can be modified. – Mooing Duck Jan 06 '15 at 23:31
  • 1
    I think of an array as its content, and nothing more. It's implicitly convertible to a pointer, but it really isn't the same thing as a const pointer. But I suppose that's a valid way to see it too. – tux3 Jan 06 '15 at 23:32
  • @MooingDuck In some cases, the string literal will be located in read only program memory. Trying to modify it in that case would cause the program to crash. I've run into this issue while programming AVR microcontrollers – SimpleJ Jan 06 '15 at 23:33
1

Even if you don't use the existing standard library function, it may still be useful to follow its interface. tolower converts an individual character. Applying this function to a string can be written as a de-coupled function.

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

int to_lower (int c) {
    if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c))
        c = c - 'A' + 'a';
    return c;         
}

void mapstring (char *str, int (*f)(int)) {
    for (; *str; str++)
        *str = f(*str);
}

int main() {
    char s[] = "THIS IS MY STRING";

    mapstring(s, to_lower);
    printf("%s\n", s); 
    return 0;
}
luser droog
  • 18,988
  • 3
  • 53
  • 105
  • The first line of the question explicitely says that it's trying to do it "without the use of tolower from ctype.h", though. – tux3 Jan 07 '15 at 00:56
  • @tux3 Thanks. I've re-written my suggestion. The point was separating the functions, not just re-using the library but imitating it. – luser droog Jan 07 '15 at 07:47
0

Two problems that I can see immediately: (1) char *s = "This..." creates a non-writable string. You need to use a character array and copy a string into it. (2) if (*temp > 'A' && *temp < 'Z') skips A and Z. You need >= and <=.

Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55