1

所以我有一个函数,它接受一个字符串,去掉特殊格式的字符,并将它分配给另一个字符串以供以后处理。

一个示例调用将是:

act_new("$t does $d");

它应该去掉 $t 和 $d 并将第二个字符串保留为“does”,但它没有分配任何东西。经过几年的闲置后,我重新开始编程,这是别人的代码(A MUD 代码库,Rom),但我觉得我缺少指针分配的基本内容。有小费吗?

(这是截断的代码,其余的直到很久以后才对 str 或 point 进行任何操作)

void act_new(const char *format)
{
  const char *str;
  char *point;

  str = format;

  while ( *str != '\0' ) {
    if ( *str != '$' ) {
      *point++ = *str++;
      continue;
    }
  }
}
4

2 回答 2

0

正如评论中所指出的,您的代码存在一些问题:

  • point未初始化(垃圾指针值)
  • continue什么都不做
  • $如果遇到a 则无限循环

在编写函数时,还必须记住,如果$遇到 a 当且仅当它不是字符串中的最后一个字符(除了'\0'),则跳过一个额外的字符。

由于您知道需要循环多少次,因此for循环更适合,并且作为奖励,您不必明确检查 a 之后的字符$是否是'\0'在跳过额外字符时formatsrc下面重命名)。另外,不要忘记终止目标字符串。

此代码将为您处理这些事情:

void act_new(const char *src)
{
    const size_t length = strlen(src);
    char * const dst = (char*)malloc(sizeof(char)*(length+1));
    if(dst == NULL)
        // Error handling left out
        return;

    char *point = dst;

    for(size_t i = 0; i < length; ++i)
    {
        if(src[i] == '$')
        {
            ++i;
            continue;
        }
        *point++ = src[i];
    }
    *point = '\0';  //Terminate string properly

    printf("%s\n", dst);
    free(dst);
}
于 2021-10-13T16:06:22.050 回答
0

您需要在str每次循环中递增,而不仅仅是在分配给point. 否则,当字符与条件不匹配时,您将陷入无限循环if

你还想跳过后面的字符$,所以遇到的时候要加str两次$

如果您使用for循环和数组索引而不是指针算法,则代码会更简单。

size_t len = strlen(format);
for (size_t i = 0; i < len; i++) {
    if (format[i] == '$') {
        i++; // extra increment to skip character after $
    } else {
        *point++ = format[i];
    }  
}
于 2021-10-13T15:40:03.457 回答