我在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++;
}
}
答案 0 :(得分:10)
当你称之为:
时,你几乎肯定会失败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;
}
答案 1 :(得分:3)
通常认为在对字符串进行操作的函数中接受长度参数是一种好的形式。这样,如果传入一个非空终止的字符串,该函数将不会循环到输入的末尾。
您可以使用调试器逐步执行函数调用,或者在循环中添加print语句并查看它迭代的次数。
答案 2 :(得分:0)
虽然你的函数ToLower()
的名称暗示你正在重写tolower()
的ANSI C版本,(即将一个字符从大写改为小写),你的实现表明你真的想要一个整体要更改的字符串。也许名称StrToLower()
是你真正想要的? (即改变整个字符串)。如果是这种情况,则以下代码说明。 (如果你真的想重写tolower()
,它应该是一个不同的问题,原型类似于C版本,每次调用只改变一个字符串)
这个答案假设你的问题是标签“c”,你不想要String.ToLower()
的.NET版本(它转换字符串)。如果这是一个错误的假设,请忽略我的咆哮。
此方法适用于char *str="STRING";
或常量字符串("STRING"
)作为参数。
[Expanded] 包含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);
}
结果: (回答罗兰的评论)
答案 3 :(得分:-2)
对于安全变量,您可以使用以下原型:
void ToLower(const char *str)