N00B here. This function would be easier using a char pointer along with free. But I wish to learn how to use char static pointers (they do not require free, right ?).
How do I erase the content of a static pointer ? Terminating the string works but the static pointer's content is not being erased, right ? Why is realloc not working like I want it to ?
char *STRINGtoLOWERCASE(const char *IN) // converts all chars in string to lower case (will not work on non-ASCII chars)
{
static char *OUTPUT = NULL;
if(OUTPUT == NULL)
{
OUTPUT = (char *)malloc(sizeof(IN));
}else{
OUTPUT[0] = '\0'; // Why will this not erase the string ???
OUTPUT = (char *)realloc(OUTPUT, sizeof(IN));
}
int COUNT = 0;
while(IN[COUNT])
{
OUTPUT[COUNT] = (char)(tolower(IN[COUNT])); // need to cast to (char) or it will return the ASCII value no the char value
COUNT++;
}
// OUTPUT[COUNT] = '\0'; // Commenting this shows that OUTPUT is not being erased !
return OUTPUT;
}
int main(void)
{
// OUTPUT is not being erased...
puts(STRINGtoLOWERCASE("HeLlO WoRlD")); // hello world
puts(STRINGtoLOWERCASE("HeLlO")); // hello world
puts(STRINGtoLOWERCASE("HeLlO WoRlD"));// hello world
return 0;
}
if(OUTPUT == NULL)
{
OUTPUT = (char *)malloc(sizeof(IN));
}else{
OUTPUT[0] = '\0'; // Why will this not erase the string ???
OUTPUT = (char *)realloc(OUTPUT, sizeof(IN));
}
The malloc/realloc size is wrong. Note that sizeof(IN) is the size of a pointer to char (i.e. 4 or 8 bytes depending on your processor architecture), and not the size of the string. You need to use strlen().
OUTPUT[0]='\0' is not needed.
Note that realloc() doesn't set newly area to 0:
So you need to properly terminate the string with '\0'.
int COUNT = 0;
while(IN[COUNT])
{
OUTPUT[COUNT] = (char)(tolower(IN[COUNT])); // need to cast to (char) or it will return the ASCII value no the char value
COUNT++;
}
// OUTPUT[COUNT] = '\0'; // Commenting this shows that OUTPUT is not being erased !
uncomment OUTPUT[COUNT]='\0'. string needs to be zero terminated in C.
Finally, it's unusual to write function or variable names in C USING UPPER CASE.
POST UPDATE: Thanks for the heads up on the strlen vs sizeof. It also needs to add 1 to include the string terminator. here is the final version:
char *STRINGtoLOWERCASE(const char *IN) // converts all chars in string to lower case (will not work on non-ASCII chars)
{
static char *OUTPUT = NULL;
if(OUTPUT == NULL)
{
OUTPUT = (char *)malloc(strlen(IN) + 1);
}else{
OUTPUT = (char *)realloc(OUTPUT, strlen(IN) + 1); // I am still not sure if this actually is reallocating. Can you realloc a static pointer ? (In C, there is no standard function to find out the size of allocated memory.)
}
int COUNT = 0;
while(IN[COUNT])
{
OUTPUT[COUNT] = (char)(tolower(IN[COUNT])); // need to cast to (char) or it will return the ASCII value no the char value
COUNT++;
}
OUTPUT[COUNT] = '\0';
return OUTPUT;
}
Whether the pointer is static, const, or plaid green monkey has no effect on the memory it points to.
And I don't think your static variable there is doing what you think it does. You have the rough idea, it acts like a global, but I don't understand why you're using one here. Why preserve a pointer between function calls when each realloc() would almost certainly invalidate every pointer given before by STRINGtoLOWERCASE anyway?
Never call realloc() or free() on memory that didn't ultimately come from a calloc(), malloc(), or strdup(). This is true no matter what kind of pointer you store it in -- the realloc() call really has no way to tell the difference. If it's failing it's failing for other reasons.
In your code, char* OUTPUT should be declared static. Otherwise, you shall run into serious troubles.
Your second paragraph just explain why it has to be static if you go for a realloc! It is true that realloc invalidates the pointer, but to do so it needs first a valid pointer that comes from a realloc() or malloc()...