0

我正在用 C 编写自己的 ToLower(char *str) 实现。但是我在函数中遇到了分段错误。我写的函数是:

void ToLower(char *str)
{
    while(*str != '\0')
    {
        if(*str >=65 && *str<=90)
        {
            // It fails in the below assignment
            *str = *str + 32;
        }
        str++;
    }

}
4

4 回答 4

11

当你这样称呼它时,你几乎肯定会失败:

int main(void)
{
    ToLower("HelloWorld");
    return 0;
}

这是因为"HelloWorld"它是一个文字常量字符串,您无法更改其内容。

请尝试:

int main(void)
{
    char str[] = "HelloWorld";

    // Now str is your own local buffer, that you can modify.
    // It is initialized with the text, but that text can be changed.
    ToLower(str);
    return 0;
}
于 2013-10-10T15:57:56.653 回答
4

通常认为在对字符串进行操作的函数中接受长度参数是一种很好的形式。这样,如果您传入一个非空终止的字符串,该函数将不会循环超过输入的末尾。

您可以使用调试器单步执行函数调用,或者在循环中添加打印语句并查看它迭代了多少次。

于 2013-10-10T15:57:22.673 回答
0

尽管您的函数名称ToLower()表明您正在重写 , 的 ANSI C 版本tolower()(即将一个字符从大写更改为小写),但您的实现表明您确实希望更改整个字符串。也许这个名字StrToLower()是你真正想要的?(即更改整个字符串)。如果是这种情况,下面的代码说明了。(如果你真的要重写tolower(),那应该是另外一个问题,原型类似于C版本,每次调用只改变一个字符)

这个答案假设因为你的问题中的标签“c”,你不想要.NET版本String.ToLower()(它确实转换了一个字符串)。如果这是一个错误的假设,请忽略我的咆哮。

此方法将使用char *str="STRING";,或使用常量字符串 ( "STRING") 作为参数。
[扩展]包括 ToLower 的实现,以防 OP 真正想要的。

#include <stdio.h>
char * StrToLower(char *str) ;
int toLower(int chr);

int main(void)
{
    char lowered[] = "UPPER to Lower"; 

    sprintf(lowered, "%s",StrToLower(lowered));
    printf("%s\n", lowered); //works with a variable buffer argument

    lowered[0]=0;//clear the buffer

    sprintf(lowered, "%s",StrToLower("UPPER to Lower")); 
    printf("%s\n", lowered); //also works with a literal string argument

    getchar();//view results
    return 0;
}

char * StrToLower(char *str)
{
    char *pNew1 = str;
    char *pNew2 = str;

    if(str != NULL) //NULL ?
    {
        if(strlen(str) != 0) //"" ?
        {
            while(*pNew1)
            {
                *pNew2 = toLower(*pNew1); 
                ++pNew2;
                ++pNew1;
            }
            *pNew2 = '\0';
            return str;// return changed string
        }              // and prevent returning null to caller
    }
    return "";//Will never get here for non-null input argurment
}   

int toLower(int chr)//touches only one character per call
{
    return (chr >='A' && chr<='Z') ? (chr + 32) : (chr);    
}

结果:(回答罗兰的评论)
在此处输入图像描述

于 2013-10-10T16:51:01.443 回答
-2

对于安全变量,您可以使用以下原型:

void ToLower(const char *str)
于 2013-10-10T16:16:10.657 回答