C如何知道我的字符串的结尾?

时间:2012-04-27 11:31:32

标签: c string

我有一个程序,我想从字符串中删除空格。我想找到一种优雅的方法,所以我找到了以下内容(我已经改变了一点,因此它可以更好阅读)代码in a forum

char* line_remove_spaces (char* line)
{
    char *non_spaced = line;
    int i;
    int j = 0;
    for (i = 0; i <= strlen(line); i++)
    {
        if ( line[i] != ' ' )
        {
            non_spaced[j] = line[i];
            j++;
        }
    }
    return non_spaced;
}

如您所见,该函数采用一个字符串,并使用相同的已分配内存空间,仅选择非间隔字符。它有效!

无论如何,根据维基百科,C中的字符串是“Null-terminated string”。我总是这么想,一切都很好。但问题是:我们在non_spaced字符串的末尾没有放置“null-character”。并且不知何故,编译器知道它以“non_spaced”字符串改变的最后一个字符结束。怎么知道?

7 个答案:

答案 0 :(得分:9)

魔法不会发生这种情况。你的代码中有:

for (i = 0; i <= strlen(line); i++)
              ^^

循环索引i一直运行到strlen(line),并且在此索引处,字符数组中有一个空字符,这也会被复制。因此,您的最终结果在所需索引处具有零字符。

如果你有

for (i = 0; i < strlen(line); i++)
              ^^

然后你必须手动将nul字符放在:

for (i = 0; i < strlen(line); i++)
{
    if ( line[i] != ' ' )
    {
        non_spaced[j] = line[i];
        j++;
    }
}
// put nul character
line[j] = 0;

答案 1 :(得分:5)

其他人已经回答了你的问题,但这是相同代码的更快,更清晰的版本:

void line_remove_spaces (char* line)
{
  char* non_spaced = line;

  while(*line != '\0')
  {
    if(*line != ' ')
    {
      *non_spaced = *line;
      non_spaced++;
    }

    line++;
  }

  *non_spaced = '\0';
}

答案 2 :(得分:2)

循环使用<= strlen,因此您也将复制空终止符(位于i == strlen(line))。

答案 3 :(得分:0)

你可以尝试一下。在处理只包含一个空格的字符串时调试它:''。仔细观察索引i会发生什么。

答案 4 :(得分:0)

你怎么知道它“知道”?最可能的情况是,您只是运气未定义的行为,并且在'\0'的有效字节结束后有一个line字符。

你很可能最后没有看到空格,可能会在遇到迷路“幸运'\0'”之前打印出来。

其他几点:

  • 无需使用索引编写此内容。
  • 在每次循环迭代中调用strlen()效率不高。
  • 您可能希望使用isspace()删除更多空白字符。

以下是我使用isspace()和指针编写它的方法:

char * remove_spaces(char *str)
{
  char *ret = str, *put = str;

  for(; *str != '\0'; str++)
  {
    if(!isspace((unsigned char) *str)
      *put++ = *str;
  }
  *put = '\0';

  return ret;
}

请注意,此 终止字符串的无空间版本,因此返回的指针保证指向有效的字符串。

答案 5 :(得分:0)

你的函数的字符串参数是以null结尾的,对吗? 在循环中,原始字符串的空字符也会复制到非间隔返回的字符串中。所以非间隔字符串实际上也是以空值终止的!

对于你的编译器,空字符只是另一个没有得到任何特殊处理的二进制数据,但字符串API使用它作为一个方便的字符来轻松检测字符串的结尾。

答案 6 :(得分:0)

如果你使用&#34;&lt; = strlen(line),strlen(line)的长度包括&#39; \ 0&#39; 所以你的程序可以工作。你可以使用调试和运行分析。