【问题标题】:Concatenating strings with special ending characters in C在C中连接具有特殊结束字符的字符串
【发布时间】:2018-10-28 08:06:31
【问题描述】:

我正在学习 C 并尝试实现一个函数

char *es_cat(char *dst, char *src)

将字符串src 添加到dst 的末尾,但有一点扭曲:字符串被认为以'?' 字符而不是通常的'\0' 结尾。创建的字符串必须以'?' 结尾,但忽略第一个字符串的'?'。这是我的尝试:

/* A simple function to determine the length of a string according to the
 * previously stated '?' constraint.
 */
unsigned int es_length(const char *s)
{
    const char *c = s;
    int amount = 0;
    while (*c != '?')
    {
        amount++;
        c++;
    }
    return amount;
}

char *es_cat(char *dst, char *src)
{
    int total = es_length(dst) + es_length(src) + 1; // + 1 for the last '?'
    char buffer[total]; 
    char *b = buffer;

    /* Copy the dst string. */
    while (*dst != '?')
    {
        *b = *dst;
        dst++;
        b++;
    }

    /* Concatenate the src string to dst. */
    while (*(src-1) != '?')
    {
        *b = *src;
        src++;
        b++;
    }
    printf("\n%s", buffer);
    return buffer;
}

int main(void)
{
    char cat_dst[] = "Hello ?"; // length according to es_length = 6
    char cat_src[] = "there! - Well hel?"; // length according to es_length = 17
    es_cat(cat_dst, cat_src);
    return 0;
}

现在,当我运行时,我期待输出:Hello there! - Well hel?。字符串基本相同,但后面跟着 3 个字符的垃圾(准确地说,现在的输出是 Hello there! - Well hel?■@)。当我从 cat_src 字符数组中添加或删除 3 个字符时,垃圾字符消失了。我是错误地初始化了缓冲区还是我把指针弄乱了?

另一方面,是否可以直接连接字符串dst,即不创建缓冲区?

提前谢谢你!

【问题讨论】:

  • 打印的 c 字符串需要有一个空终止字符才能成为有效字符串。如果您只是将它从一个位置移动到另一个位置,例如在打包的消息中,您可以在没有终结符的情况下度过难关。然而,在它的最终形式中,它应该总是有一个。您可能想要验证您是否正确理解了作业,或者这就是重点。无论如何,如果没有空终止符,您所看到的都是可以预期的。
  • 你已经很接近了。为什么在第二个 while 循环中从 src 中减去 1?这是错误的,因为在循环中第一次索引 src[-1] 超出范围且未定义。此外,您返回的本地数组缓冲区也是错误的......但您没有使用它。
  • 不要忽略编译器发出的关于返回局部变量地址的警告!

标签: c string character concatenation


【解决方案1】:

也许您的函数使用不同的字符串终止符,但您仍然使用标准 C 函数来打印字符串,并且它们需要一个空终止符字符,因此,最后您必须在字符串中写入一个空终止符.

char *es_cat(char *dst, char *src)
{
    int total = es_length(dst) + es_length(src) + 2; // + 1 for the last '?' and +1 for the '\0'
    char *buffer = (char*)malloc(total);
    char *b = buffer;

    if (buffer == NULL)
        return NULL;

    /* Copy the dst string. */
    while (*dst != '?')
    {
        *b = *dst;
        dst++;
        b++;
    }

    /* Concatenate the src string to dst. */
    while (*src != '?')
    {
        *b = *src;
        src++;
        b++;
    }
    *b = '?';
    b++;
    *b = '\0';
    printf("\n%s", buffer);
    return buffer;
}

【讨论】:

  • 没有空终止符的字符串可以用%.*s打印,如printf("%.*s\n", NumberOfCharacters, String)printf("%.*s\n", (int) (EndPointer - String), String);
  • 你返回的是一个局部变量的地址。
猜你喜欢
  • 2020-08-13
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 2012-09-07
  • 2021-01-21
  • 2019-09-03
  • 2019-09-10
相关资源
最近更新 更多