如何编写 return 动态分配字符串的函数?

How to write function that return dynamic allocated string?

我的任务是使用函数 char *slova(const char *s),其中 returns 动态分配仅由大小字母组成的字符串。禁止使用string.h库。

char *slova(const char *s)
{
    char *new;
    int br = 0;
    new = (char *)malloc(sizeof(s));
    for (int i = 0; i != '[=11=]'; i++)
        if(s[i] >= 'A' && s[i] <= 'z')
        {
            new[br] = s[i];
            br++;
        }
    return new;
}

我知道ASCII码中A和z之间除了大小写字母外还有一些其他字符,所以不用担心。出于某种原因,这段代码不起作用,我不知道为什么。

  • sizeof(s) 将 return 不是缓冲区大小而是指针的大小 s.
  • i != '[=13=]' 是错误的。这意味着 i != 0 并阻止它进入循环,因为 i 的初始值是 0.
  • 您忘记通过添加终止空字符来终止结果字符串。
  • 在C中转换malloc()的结果是discouraged

固定码:

char *slova(const char *s){
    char *new;
    int br = 0;

    // calculate the length
    for (int i = 0; s[i] != '[=10=]'; i++)
        if(s[i] >= 'A' && s[i] <= 'z'){
            br++;
        }

    // allocate buffer
    new = malloc(br + 1);
    if (new == NULL) return NULL;

    // actually create the string
    br = 0;
    for (int i = 0; s[i] != '[=10=]'; i++)
        if(s[i] >= 'A' && s[i] <= 'z'){
            new[br] = s[i];
            br++;
        }

    new[br] = '[=10=]';
    return new;
}

仔细查看你的函数声明

char *slova(const char *s){
            ^^^^^^^^^^^^^

其参数为指针类型const char *。因此在这个声明中

new = (char *)malloc(sizeof(s));

表达式 sizeof(s) 产生的指针大小通常等于 84 字节,具体取决于所使用的系统。那就是这个表达式没有提供传递的字符串的长度。

也是这个循环的body

for (int i = 0; i != '[=12=]'; i++)

永远不会获得控制权,因为条件 i != '[=21=]' 立即计算为 false 因为变量 i 被初始化为零。

该函数可以如下面的演示程序所示。它不使用 header <string.h>.

中的函数
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

char * slova( const char *s )
{
    size_t n = 0;
    
    for ( const char *t = s; *t != '[=13=]'; ++t )
    {
        if ( isalpha( ( unsigned char )*t ) ) ++n;
    }
    
    char * result = malloc( ( n + 1 ) *sizeof( char ) );
    
    if ( result != NULL )
    {
        char *p = result;
        for ( ; *s; ++s)
        {
            if ( isalpha( ( unsigned char )*s ) )
            {
                *p++ = *s;
            }
        }
        
        *p = '[=13=]';
    }
    
    return result;
}   

int main(void) 
{
    const char *s = "H#e#l#l#o W#o#r#l#d";
    
    char *p = slova( s );
    
    if ( p ) puts( p );
    
    free( p );
    
    return 0;
}

程序输出为

HelloWorld

如果不允许您也使用 header <ctype.h> 中的函数,那么该函数可以如下面的演示程序所示。

#include <stdio.h>
#include <stdlib.h>

char * slova( const char *s )
{
    const char *upper_case = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const char *lower_case = "abcdefghijklmnopqrstuvwxyz";
    
    size_t n = 0;
    
    for ( const char *t = s; *t != '[=15=]'; ++t )
    {
        const char *letter = lower_case;
        
        if ( *t < lower_case[0] )
        {
            letter = upper_case;
        }
        
        while ( *letter && *letter < *t ) ++letter;
        
        if ( *letter == *t ) ++n;
    }
    
    char * result = malloc( ( n + 1 ) *sizeof( char ) );
    
    if ( result != NULL )
    {
        char *p = result;
        
        for ( ; *s; ++s)
        {
            const char *letter = lower_case;
            
            if ( *s < lower_case[0] )
            {
                letter = upper_case;
            }
            
            while ( *letter && *letter < *s ) ++letter;
            
            if ( *letter == *s )
            {
                *p++ = *s;
            }
        }
        
        *p = '[=15=]';
    }
    
    return result;
}   

int main(void) 
{
    const char *s = "H#e#l#l#o W#o#r#l#d";
    
    char *p = slova( s );
    
    if ( p ) puts( p );
    
    free( p );
    
    return 0;
}

程序输出同样是

HelloWorld