【问题标题】:Return a trimmed string using pointers使用指针返回修剪后的字符串
【发布时间】:2014-11-17 22:24:25
【问题描述】:

我正在尝试使用指针修剪字符串(从字符串的开头和结尾删除空格)。

char* killspace(char *a)
{
    char *enda = NULL;
    int i = 0, spaceS = 0, spaceE = 0, bigend = 0 , out = 0, taille = strlen(a); 
    do
    {
        if (a[i] == ' ')
        {
            spaceS++;   
        }
        else
        {
            out = 1;
        }
        i++;
    } while (out == 0);
    out = 0;
    do
    {
        if (a[taille] == ' ')
        {
            spaceE++;
        }
        else
        {
            out = 1;
        }
        taille--;
    } while (out == 0);
    bigend = (spaceE + spaceS);
    // new size
    enda = (char *)calloc((strlen(a)-bigend), sizeof(char));
    i = 0;
    for (int j = spaceS; j < (strlen(a)-spaceE); j++)
    {
        enda[i] = a[j];
        i++;
    }
    return(enda);
    free(enda);
    
}

bigend 是字符串开头和结尾的空格数。

但返回的结果有一些随机字符,如“ýýýý««««««««îþîþîþ”

【问题讨论】:

  • 您忘记在字符指针末尾添加“\0”来以空值结尾。
  • 无条件return之后的free()应该达到什么目的?
  • 我把free释放内存,没有条件返回
  • free 永远不会被执行。你的编译器会警告你。您确实启用了警告,然后正确地阅读了它们?

标签: c pointers dynamic-memory-allocation


【解决方案1】:

将起始地址更改为字符串,需要 (1) 将地址作为参数发送到保存字符串的指针,以便可以更改它或 (2) 从函数返回一个指针,指向修剪后的字符串的新开头。后者可能是你最好的选择。这是一个例子:

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

char *trimstr (char *s)
{
    while (isspace(*s))     /* while space, increment pointer   */
        s++;

    char *p = s;            /* pointer to string s              */
    while (*p) p++;         /* advance pointer to end of s      */
    p--;                    /* decrement pointer off null-term  */

    while (isspace(*p))     /* while space, set new end of str  */
    {
        *p = 0;
        p--;
    }

    return s;               /* return pointer to trimmed string */
}

int main () {

    char mystring[] = "  some string with leading/trailing WS  ";
    char *p = mystring;

    printf ("\n  Original String: '%s'\n\n", mystring);

    p = trimstr (mystring);

    printf ("  Trimmed String : '%s'\n\n", p);

    return 0;
}

输出:

$ ./bin/trimstr

  Original String: '  some string with leading/trailing WS  '

  Trimmed String : 'some string with leading/trailing WS'

以这种方式解决问题通常会缩短代码,尝试执行 "index-shuffle" 以将字符串中的所有字符向下移动以覆盖前导空格。但是,"index-shuffle" 并没有什么问题,您只需要特别注意偏移量并记住还要偏移null-terminator

如果您对节省代码行感兴趣,可以编写一个更紧凑但可读性稍差的trimstr 函数版本,如下所示:

char *trimstr (char *s)
{
    while (isspace(*s)) s++;        /* while space, increment pointer   */
    char *p = s;                    /* pointer to string s              */
    while (*p) p++;                 /* advance pointer to end of s      */
    while (isspace(*(--p))) *p = 0; /* while space, set new end of str  */
    return s;                       /* return pointer to trimmed string */
}

【讨论】:

  • 很高兴它对您有用。花点时间逐步了解所使用的指针逻辑。这是一个非常好的例子,可以帮助巩固 C 中指针的使用。一个很好的方法是将字符串 ' ws ' 作为输入,然后在一张纸上画出正在发生的事情。指针是 C 语言中最令人困惑(直到学会)但功能强大的概念之一。
【解决方案2】:

在我的情况下,我发现了这个问题,我在字符串的末尾添加了一个限制器 enda[i] = '\0';,它对我有用

【讨论】:

    猜你喜欢
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 2022-01-02
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 2012-07-14
    相关资源
    最近更新 更多