问题描述
我正在尝试编写一个函数,该函数从字符串中删除空格,并将其转换为小写。
char *removeSpace(char *st);
int main(void){
char *x = "HeLLO WOrld ";
x = removeSpace(x);
printf("output: %s\n",x);
}
char *removeSpace(char *st)
{
int c = 0;
char *s = malloc(sizeof(strlen(st)+1));
for (int x = 0; x < strlen(st); x++)
{
if (st[x] != ' ')
{
s[x] = tolower(st[x]);
}
}
st= s;
st= s;
return st;
}
解决方法
char *s = malloc(sizeof(strlen(st)+1));
您有几个嵌套表达式,并且您在注释线程中完全错误地跳了 (我猜是50:50)。
-
strlen(st)
是字符串st
-
strlen(st)+1
是分配给副本的正确字符数...到目前为止看起来还不错!
-
sizeof(strlen(st)+1)
是表示该值的 type 所需的字节大小。因此,如果size_t
是4字节的unsigned int
,则此sizeof表达式仅为4
。此时字符串长度的值被丢弃。
现在,您要为字符串分配足够的字节,而又没有足够的字节来将字符串的长度保存为size_t
值。只需完全删除sizeof
。
哦,还有-st = s
在这里什么也没做。变量st
在函数内部,不影响外部任何内容。返回s
就足够了。
如注释中所述,malloc语句不必要地使用sizeof。在将字符分配给新字符串时,您还存在一个错误:
s[x] = tolower(st[x]);
您对新字符串s使用与旧字符串st相同的索引。删除任何空格后,这是不对的。因此,例如,当您复制 hello 时,两个字符串之间的索引0到4排成一行,但随后您跳过了索引5的空格,然后想要在st处分配 w [6]至s [5]。这意味着您需要一个单独的索引来跟踪您在目标字符串中的位置。因此,您需要类似以下代码的代码,该代码清理malloc(),添加缺少的标头,并为输出字符串引入新的索引:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *removeSpace(char *st);
int main(void){
char *x = "HeLLO WOrld ";
x = removeSpace(x);
printf("output: %s\n",x);
}
char *removeSpace(char *st)
{
size_t len = strlen(st);
int newStrIdx = 0;
char *s = malloc(len+1);
for (int x = 0; x < len; x++)
{
if (st[x] != ' ')
{
s[newStrIdx++] = tolower(st[x]);
}
}
s[newStrIdx] = '\0';
return s;
}
哦,您忘记了我在末尾添加的输出字符串的空终止。
,对于初学者来说,如果要创建字符串的副本,则函数声明应类似于
char * removeSpace( const char *st);
即原始字符串在函数中未更改。
当您向函数传递字符串文字时
char *x = "HeLLO WOrld ";
x = removeSpace(x);
那么实际上它可能无法在函数中更改。任何更改字符串文字的尝试都会导致未定义的行为。
调用malloc
sizeof(strlen(st)+1)
等同于表达式
sizeof( size_t )
由于函数strlen
具有返回类型size_t
。
因此,此表达式不会产生源字符串的长度。
此外,无需分配大小等于源字符串大小的字符串,因为目标字符串(由于除去空格)的字符可以比源字符串少得多。
if语句中的赋值
if (st[x] != ' ')
{
s[x] = tolower(st[x]);
}
在表达式s[x]
中使用无效索引。因此,目标字符串将包含带有未初始化字符的空格。
此外,结尾的零字符'\0'
不会附加到目标字符串
请注意,空格字符集除空格字符'\t'
之外还包括其他字符,例如制表符' '
。
可以通过以下方式定义功能。
char * removeSpace( const char *st )
{
size_t n = 0;
for ( const char *src = st; *src; ++src )
{
if ( !isspace( ( unsigned char )*src ) ) ++src;
}
char *result = malloc( n + 1 );
result[n] = '\0';
for ( char *dsn = result; *st; ++st )
{
if ( !isspace( ( unsigned char )*st ) )
{
*dsn++ = tolower( ( unsigned char )*st );
}
}
return result;
}
该函数可以像
那样调用char *st = "HeLLO WOrld ";
char *dsn = removeSpace( st );
puts( dsn );
free( dsn );
这是一个演示程序。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char * removeSpace( const char *st )
{
size_t n = 0;
for ( const char *src = st; *src; ++src )
{
if ( !isspace( ( unsigned char )*src ) ) ++src;
}
char *result = malloc( n + 1 );
result[n] = '\0';
for ( char *dsn = result; *st; ++st )
{
if ( !isspace( ( unsigned char )*st ) )
{
*dsn++ = tolower( ( unsigned char )*st );
}
}
return result;
}
int main(void)
{
char *st = "HeLLO WOrld ";
char *dsn = removeSpace( st );
puts( dsn );
free( dsn );
return 0;
}
其输出为
helloworld