C 字符串复制函数未正确复制字符串。什么';我的代码怎么了?

C 字符串复制函数未正确复制字符串。什么';我的代码怎么了?,c,whitespace,c-strings,removing-whitespace,function-definition,C,Whitespace,C Strings,Removing Whitespace,Function Definition,我试图编写一个函数,从字符串中删除WhiteAPCEs并将其转换为小写 我下面的代码没有返回任何内容。为什么? char *removeSpace(char *st); int main(void){ char *x = "HeLLO WOrld "; x = removeSpace(x); printf("output: %s\n", x); } char *removeSpace(char *st) { int

我试图编写一个函数,从字符串中删除WhiteAPCEs并将其转换为小写

我下面的代码没有返回任何内容。为什么?

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*removeSpace(char*st);
内部主(空){
char*x=“你好,世界”;
x=移动空间(x);
printf(“输出:%s\n”,x);
}
char*removeSpace(char*st)
{
int c=0;
char*s=malloc(sizeof(strlen(st)+1));
对于(int x=0;x
您有两个嵌套表达式,在注释线程中跳错了方向(我猜是50:50)

  • strlen(st)
    是字符串
    st

  • strlen(st)+1
    是为副本分配的正确字符数

    。。。到目前为止看起来不错

  • sizeof(strlen(st)+1)
    是表示该值类型所需的字节大小。因此,如果
    size\u t
    是一个4字节的
    unsigned int
    ,那么这个sizeof表达式就是
    4

    此时将丢弃字符串长度的值

现在,您需要为字符串分配足够的字节,而不是将字符串长度保存为
size\t
值。只需完全删除
的大小即可


哦,而且-
st=s
在这里什么都不做。变量
st
是函数内部的局部变量,不会影响函数外部的任何内容。返回
s
就足够了。

如注释中所述,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: %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(char*st);
内部主(空){
char*x=“你好,世界”;
x=移动空间(x);
printf(“输出:%s\n”,x);
}
char*removeSpace(char*st)
{
尺寸长度=标准长度(st);
int newStrIdx=0;
char*s=malloc(len+1);
对于(int x=0;x

哦,您忘记了null终止输出字符串,这是我在末尾添加的。

首先,如果您想创建字符串的副本,那么函数声明应该如下所示

char * removeSpace( const char *st);
也就是说,函数中的原始字符串没有更改

当您将字符串文本传递给函数时

char *x = "HeLLO WOrld ";

x = removeSpace(x);
那么实际上,它可能不会在函数中更改。任何更改字符串文字的尝试都会导致未定义的行为

调用
malloc

sizeof(strlen(st)+1)
与表达式相同

sizeof( size_t )
由于函数strlen
具有返回类型
size\u 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;
}

sizeof(strlen(st)+1)
只是
sizeof(size\u t)
,通常会太小。提示:不要将
strlen
结果包装为
sizeof
,这将丢弃该值。很可能无法修改字符串文字。我建议
charx[]=“你好,世界”
sizeof(st)是否正确?@WeatherVane我尝试了一下,得到了这个错误str.c:12:4:error:assignment到数组类型为12 | x=normaliseWord(x)的表达式@HSWY:不。请使用
malloc(strlen(st)+1)
。非常感谢您提供的详细答案!除了修复程序外,还学到了很多东西
#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