Search code examples
cstringlowercase

How to make a string lowercase without modifying the original in C?


I am working with a function that takes a pointer to a string as an argument and returns it in lower-case:

char* strLower(char* s) {
    for(char *p=s; *p; p++) *p=lower(*p);
    return s;
}

As of right now, it does return the lower-case string correctly, but it also modifies the original string (the one taken as an argument) outside of the function itself. How can I avoid this?


Solution

  • For doing this, the function will need some allocated memory to store the result. There are at least three strategies:

    1. You can provide this memory as a result buffer to the function:
    char* strLower(const char* src, char *dest) { ...
    

    In this case, it is the callers responsibility that the size of the dest buffer is sufficient.

    1. The function can allocate the memory itself:
    char* strLower(const char* src) {
       char *dest = malloc(1+strlen(src));
       ...
    

    In this case, it is the callers responsibility to free the allocated memory when it is no longer used (otherwise there will be a memory leak). Unless there is a good reason for this option, I do not recommend it because dynamic memory allocation should usually have clearly symmetric calls to malloc and free to make sure that memory is freed. In this case it is not obvious that a call to strLower() will allocate memory.

    1. The function can have a statically allocated buffer:
    #define MAX_STRING_SIZE 80+1
    char* strLower(const char* src) {
       static char dest[MAX_STRING_SIZE];
       ...
    

    In this case, the caller must be aware that the returned string will be overwritten next time strLower() is called.

    None of the above possibilities are ideal so unless there is a reason against it, I would recommend to keep the function as it is. The caller can then copy the original string (e.g. using strdup()) in case both versions of the string are needed. This will avoid overhead of copying/memory allocation if it is not needed and make it clear that the caller has the responsibility to free any allocated memory.