大写字符串并返回局部变量

时间:2013-11-29 20:15:12

标签: c string

我正在尝试创建一个大写字符串的过程,但是我得到了垃圾值和来自gcc的警告,我正在返回一个局部变量的地址。来自Python,我对此问题感到困惑。 (不想使用<string.h>

中的内容
 2
 3
 4char* strcaps(const char *strlower)
 5{
 6  int len = 0;
 7  while (*strlower != '\0'){
 8    len++;
 9    strlower++;
10  }
11  char newStr[len + 1];
12  int i;
13  for (i = 0; i < len; i++)
14    newStr[i] = strlower[i] - 32;
    newStr[len + 1] = '\0';    //EDIT, just put this in.
15  return newStr;
16}
17
18int main(void)
19{
20  
21  
22  
23  printf("I expect capitalized version of edgar, I got %s\n", strcaps("edgar"));
24
25
26  return 0;
27}

我猜我可以创建一个全局字符串,然后可变,但是我宁愿将所有内容保留在函数strcaps中...这是我应该使用malloc的情况吗?

由于

编辑:刚刚意识到我从未在新字符串的末尾放置'\0,尽管我不确定这是否相关。

3 个答案:

答案 0 :(得分:2)

C中有两个选项。

1)您可以向函数传递指向字符串的指针,函数将修改它并返回void

在这种情况下,您只需使用原始字符串

即可

2)你可以传递你的函数const char*并返回char *,但是你需要在函数内部使用malloc

如果您执行malloc inside函数,则可以在您调用的程序free

中使用字符串(打印或执行任何操作)

答案 1 :(得分:1)

  

这是我应该使用malloc的情况吗?

是的,确实。

在您的情况下,返回指向局部变量的指针,该函数在执行后将被销毁(变量)。这使得指针悬空。

使用malloc将在堆中创建字符串,而不是堆栈,并且在函数返回后它将保持有效。

答案 2 :(得分:0)

首先,您应该始终在字符串的末尾添加一个空字符,因为标准库使用它来表示字符串的实际结束,以防止遍历内存。

这是一项实施。

/* Makes a copy of the string as to not modify the original buffer */
char* makeCopy(char* s){

    char* buff = (char*) malloc(len(s) + 1);
    strcpy(buff, s);
    return buff;
}

/* Converts the string to uppercase */
char* toUpperCase(char* s){

        char* q = makeCopy(s);
        int i;
        for(i = 0; i < len(q); i++){
                *(q + i) = toupper(*(q + i));
        }

        return q;

}

现在你可以做到:

printf("I expect capitalized version of edgar, I got %s\n", toUpperCase("edgar"));

现在我明白你不想触及string.h中的任何内容,但它很有用,因为如果没有这些功能,你可能需要自己实现很多东西。

例如,函数toupper()来自string.h。这会将字符转换为大写的等效字符。如果你坚持重新发明轮子,你可以破解一个处理它的小功能。

char getUpperCaseChar(char lower){
    if(lower < 91)
        return lower;
    if(lower > 96)
        return (lower - 32);
}