我正试图编写一个函数,从字符串中删除whitesapces并将其转换为小写。
我下面的代码没有返回任何内容。为什么?
char *removeSpace(char *st);
int main(void){
char *x = "HeLLO WOrld ";
x = removeSpace(x);
printf("output: %sn", 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;
}
malloc语句不必要地使用了sizeof,如注释中所述。在将字符分配给新字符串时也出现错误:
s[x] = tolower(st[x]);
您对新字符串s使用与旧字符串st相同的索引。一旦删除任何空格,这是不对的。例如,当您复制hello时,索引0到4在两个字符串之间排列,但随后您跳过索引5处的一个空格,然后您想将st[6]处的w分配给s[5]。这意味着您需要一个单独的索引来跟踪您在目标字符串中的位置。因此,您需要这样的代码,它清理malloc((,添加丢失的头includes,并为输出字符串引入一个新的索引:
#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: %sn", 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] = ' ';
return s;
}
哦,你忘了null终止输出字符串,我在末尾添加了它。
char *s = malloc(sizeof(strlen(st)+1));
您有几个嵌套的表达式,并且在注释线程中以错误的方式跳过了(我猜是50:50(。
strlen(st)
是字符串st
中的字符数strlen(st)+1
是为复制分配的正确字符数到目前为止看起来不错!
sizeof(strlen(st)+1)
是表示该值的类型所需的字节大小。因此,如果size_t
是一个4字节的unsigned int
,那么这个大小的表达式就是4
。此时字符串长度的值被丢弃。
现在,您想要为字符串分配足够的字节,而不是足够的字节来将字符串的长度保存为size_t
值。只需完全移除sizeof
即可。
哦,而且st = s
在这里什么都不做。变量st
在函数内部是局部的,不会影响外部的任何内容。返回s
就足够了。
对于初学者来说,如果你想创建一个字符串的副本,那么函数声明应该看起来像
char * removeSpace( const char *st);
也就是说,原始字符串在函数中没有更改。
当您将字符串文字传递给函数时
char *x = "HeLLO WOrld ";
x = removeSpace(x);
那么实际上它可能不会在函数内改变。任何更改字符串文字的尝试都会导致未定义的行为。
调用malloc
时使用的表达式
sizeof(strlen(st)+1)
相当于表达式
sizeof( size_t )
由于函数CCD_ 14具有返回类型CCD_。
因此,这个表达式不会产生源字符串的长度。
此外,不需要分配大小等于源字符串大小的字符串,因为目标字符串可以比源字符串具有更少的字符(由于删除了空格(。
if语句中的赋值
if (st[x] != ' ')
{
s[x] = tolower(st[x]);
}
在表达式CCD_ 16中使用了无效索引。因此,目标字符串将包含带有未初始化字符的间隙。
此外,终止零字符' '
没有附加到目的字符串
考虑到空白字符集包括除了空白字符' '
之外的其他字符,例如制表符'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] = ' ';
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] = ' ';
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