【问题标题】:Concat two strings through pointers not working通过指针连接两个字符串不起作用
【发布时间】:2022-01-06 11:45:31
【问题描述】:

我做了一个函数,将字符串 t 连接到字符串 s 的末尾,在我的练习中我必须为此使用指针,所以我这样做了,但是它不工作:

#include <stdio.h>

void strcat(char *s, char *t)
{
    while (*s++);

    for (*s = *t; *s = *t; s++, t++);
}

int main()
{
    char c[100] = "hello";
    char *w = " world\n";
    
    strcat(c, w);

    printf(c);
    
    return 0;
}

c 的输出总是返回“hello”而不是“hello world\n”

【问题讨论】:

  • printf("%s\n", c) 试试这样。
  • 这能回答你的问题吗? How to concat two char * in C?
  • 趁此机会学习如何使用调试器在监控变量及其值的同时逐句执行代码。
  • 失败 while (*s++); 循环的评估仅在 *s 落在终结符上时才会这样做,然后您会使用后增量跳过该终结符。因此,在串联开始之前,终止符仍然存在。将其更改为while (*s) ++s;

标签: c while-loop c-strings function-definition strcat


【解决方案1】:

函数内的这个while循环

while (*s++);

不正确。在 while 循环之后,由于后缀递增运算符,指针 s 指向终止零字符 '\0' 之后。

函数可以通过以下方式声明和定义

char * strcat(char *s, const char *t)
{
    char *p = s;

    while( *p ) ++p;

    while ( ( *p++ = *t++ ) != '\0' );

    return s;
}

另外你应该重命名函数,因为 C 中已经有标准的字符串函数strcat

这是一个演示程序。

#include <stdio.h>

char *string_cat( char *s, const char *t )
{
    char *p = s;

    while (*p) ++p;

    while (( *p++ = *t++ ) != '\0');

    return s;
}

int main( void )
{
    char c[100] = "hello";
    const char *w = " world";

    puts( string_cat( c, w ) );
}

程序输出是

hello world

【讨论】:

  • 另一种方法是:char* p = s + strlen(s);
【解决方案2】:

除了@Vlad from Moscow好回答:

本地void strcat(char *s, char *t) 假定s, t 引用的字符串在内存中不重叠。考虑下面的无限循环 if s == t

char *p = s;
while (*p) p++;
while ((*p++ = *t++ ) != 0);

标准 C 库有char *strcat(char * restrict s1, const char * restrict s2);restrict 假定没有重叠并发出可能更好的代码>否则会导致 未定义的行为 (UB)。 OP 的代码也应该使用restrict

但是我们想要做什么strcat() 并应对重叠?

// Allow strings refenced by s,t to overlap.
char *my_strcat(char *s1, const char *s2) {
  size_t s1len = strlen(s1);
  size_t s2siz = strlen(s2) + 1u;
  memmove(s1 + s1len, s2, s2siz);
  return s1;
}

int main(void) {
  char c[100] = "hello";
  const char *w = c; //" world";
  puts(my_strcat(c, w));
}

输出

hellohello

为了处理重叠,需要进行额外的工作来确定s2 的大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 2018-09-03
    相关资源
    最近更新 更多