【问题标题】:trim function halve the memory size to remove the whitespaces?修剪功能将内存大小减半以删除空格?
【发布时间】:2022-01-05 12:54:47
【问题描述】:

我必须创建一个可以执行此任务的函数(修剪函数):获取一个以 null 结尾的字符串,如果在字符串的第 0 位有空格,则删除该空格。如果空格位于字符串的末尾(在零终止符之前),则同样如此。因此,该函数基本上忽略了字符串中间的空格。

到目前为止,这是我尝试做的事情, (1) 我将“a b”字符​​串传递给 trim 函数。 (2)(空指针检查)。 (3) 我用strlen函数取了字符串的长度。

(4) (这是微妙的部分,因为逐行调试我发现了一个 for 循环内的奇怪错误)。

错误是这样的:当调试器运行for循环的第一行时,它按预期进入了循环;好的,这很好,但是当调试器运行 if 检查时,它应该是真的(因为在字符串的开头有一个空格)并且该函数应该进入 if 主体,在第一个 if 语句中,并重新分配记忆。但这不是真的,因为 realloc 永远不会被执行。为什么?

(函数必须返回指向重新分配内存的指针)。

另一个错误是“s”没有初始化,但我还是使用了它,这不是真的,因为我用“a b”字符​​串初始化了s。

char* trim(const char* s) {    
    if (s == NULL) {  
        return NULL; 
    } 
    size_t length = strlen(s);
    for (unsigned int i = 0; s[i] != '\0'; i++) { 
            

        if (s[i] == " ") {
            realloc(s, length - sizeof(char));       
        } 
    }
    return s; 

}
int main(void) {

    
    trim(" a b ");

    return 0; 
}

【问题讨论】:

  • if (s[i] == " ") { --> if (s[i] == ' ') { --> 单引号,但通常修剪函数也必须跳过制表符和换行符,考虑if (isspace((unsigned char)s[i])) {
  • 哎呀,你是对的,单引号的意思是“转换ASCII码中的字符”,所以不是字符串。谢谢,但是为什么还是不行呢?无论如何,字符串的每个 char 都以 'char' 'char' char' 'char' 的形式进行转换,那为什么它不起作用呢?
  • 使用两个指针,一个从开头开始循环直到找到一个非空白,另一个指针做同样的事情但从结尾开始,然后malloc(不需要realloc)指针+1之间的内容,memcpy新区域的内容,NUL终止新区域,就完成了
  • 这段代码有很多错误,但这里有一些与这段代码中的内存有关。您不能重新分配静态字符串" a b "realloc 返回指向新内存的指针。无论如何,简单地重新分配字符串是行不通的,因为你会丢失字符串的结尾,你仍然需要它。

标签: c dynamic-memory-allocation trim c-strings function-definition


【解决方案1】:

在 if 语句中,您试图将 char s[i] 类型的对象与隐含的字符串文字 " " 进行比较;已转换为指向其第一个元素的指针。

   if (s[i] == " ") {

很明显,这样的比较结果为逻辑假。

您需要使用整数字符常量' ' 而不是字符串字面量。

   if (s[i] == ' ') {

还有这个内存重新分配

realloc(s, length - sizeof(char));       

没有意义,因为至少重新分配的内存的地址没有存储在任何地方。

您不得触摸源字符串s。您需要动态分配一个新的字符数组并将修剪后的源字符串复制到那里。

该函数可以定义如下,如下面的演示程序所示。

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

char * trim( const char *s ) 
{
    const char *first = s;
    
    while ( isblank( ( unsigned char )*first ) ) ++first;
    
    const char *last = first + strlen( first );
    
    while ( last != first && isblank( ( unsigned char )last[-1] ) ) --last;

    size_t n = last - first;
    
    char * result = malloc( n + 1 );
    
    if ( result != NULL )
    {
        memcpy( result, first, n );
        result[n] = '\0';
    }
    
    return result;
}

int main(void) 
{
    const char *s = " a b ";
    
    printf( "\"%s\"\n", s );
    
    char *p = trim( s );
    
    printf( "\"%s\"\n", p );

    free( p );
    
    return 0;
}

程序输出是

" a b "
"a b"

在函数内而不是这个while循环

while ( isblank( ( unsigned char )*first ) ) ++first;

你可以使用函数strspn as

first += strspn( first, " \t" );

【讨论】:

  • "last[-1]" "last[-1]" 是什么意思。应该是 last[length-1] 吧?
  • @GabrielBurzacchini 表示最后一个指针指向的位置之前的字符。
  • “last”指针的当前位置是“\0”,对吧?所以 length-1 是可能的空白的位置,对吧?
  • @GabrielBurzacchini last -1 是前一个字符的位置(地址)。
猜你喜欢
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
相关资源
最近更新 更多