删除前导空格的函数不会更改调用者中的字符串?

时间:2012-03-15 02:27:26

标签: c string char whitespace

我有一个需要从字符串中删除前导空格的函数。出于某种原因,这不起作用:

static void remove_leading_spaces(char* line)
{  
   int i;
   for(i = 0; line[i] == ' '; i++);      //iterate through till whitespace     
   line = line + i;                      //  advance the pointer to point to
                                         //  the first non space character
}

例如,如果我有一个带有单个前导空格的字符串,则不会更改该字符串。

感谢大家对remove_leading_spaces的回答是正确的!

如何使用需要从调用此函数的函数返回的字符串执行此操作?我一直在尝试相同的方法,我不断得到分段错误?这是一个完全相同的概念吗?

7 个答案:

答案 0 :(得分:4)

参数以C中的值传递。因此,即使您在此处更改line的值:

line = line + i;

传递给remove_leading_spaces()的指针值不会改变。如果你想要改变调用者中的指针,你需要传递指针的地址(这是你在C中通过引用传递的方式):

static void remove_leading_spaces(char** line)
{  
   int i;
   for(i = 0; (*line)[i] == ' '; i++);     
   *line = *line + i;
}

答案 1 :(得分:2)

由于您按值传递line,因此您需要在函数内更改其副本,但您在调用代码中传递给此函数的变量不会更改。一种解决问题的方法。这是将函数指针传递给C字符串,即char **line,而不是char *line

请注意,根据您分配字符串的方式,您可能只是通过向前推进指针来泄漏内存,而您肯定无法在以后解除分配。更好的方法是将字符串的其余部分复制到其原始开始;从长远来看,它会更低效,更正确。你甚至不必改变功能签名。

答案 2 :(得分:2)

在下面的函数中,您将按值传递指针。

static void remove_leading_spaces(char* line) 

这意味着身体中line的任何更改都不会反映在来电者身上。你需要改变你的功能:

static void remove_leading_spaces(char** line) 
{   
   int i; 
   for(i = 0; (*line)[i] == ' '; i++) { } // the ';' is a HUGE TRAP prefer { }
   *line += i;
} 

修改

注意不要在此之后释放line因为你不会释放整个字符串。如果内存是动态分配的,则需要保留原始指针的备份副本以安全地释放它。

答案 3 :(得分:2)

代码只跳过空白,而不是通用空格(包括制表符,换行符等)。因此,更通用的解决方案将使用isspace()中的#include <ctype.h>(或者您将使用'空格'或'空格'而不是'空格')。

更严重的是,您找到了第一个非空白的位置,但您没有向调用函数报告此情况。请记住,值通过引用传递,包括指针。您必须将指针传递给指针(并对代码进行其他调整)以通过参数列表返回更改的值。 '这样做更简单:

static char *find_first_non_white_space(char *line)
{
    while (isspace((unsigned char)*line))
        line++;
    return line;
}

或索引:

static char *find_first_non_white_space(char *line)
{
    int i = 0;
    while (isspace((unsigned char)line[i]))
        i++;
    return &line[i];
}

如果charsigned类型,则需要进行投射,就像在某些系统上一样。

答案 4 :(得分:1)

尝试

static void remove_leading_spaces(char* line)
{
   char *copyFrom = line;
   for (; *copyFrom && ' ' == *copyFrom; ++copyFrom);
   memmove(line, copyFrom, strlen(copyFrom));
}

它会将字符串更改为前导空格后的部分。请注意,如果只有前导空格,它也可以工作。

答案 5 :(得分:1)

该函数仅修改函数范围内line的值。最简单的解决方案是remove_leading_spaces返回line + i并让调用代码将此返回值赋给其自己范围内的变量。

答案 6 :(得分:1)

当您更改方法中的指针时,它不会更改在调用端传入的指针。如果要更改它,则需要传入指向该指针(char **cpp)的指针并通过该指针((*cpp)++)进行更改。

如果字符串是malloc,请记住保存另一个指针,以便释放它。