c语言 - 字符串复制函数无法正确复制字符串。我的代码有什么问题?



我正试图编写一个函数,从字符串中删除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

相关内容

最新更新