【问题标题】:Why strcat doesn't work with pointer in C?为什么 strcat 不适用于 C 中的指针?
【发布时间】:2021-12-31 13:19:14
【问题描述】:

当我使用普通数组执行此操作时,它可以工作,但使用指针却不行。

#include <stdio.h>
#include <string.h>
int main()
{
    char source[]="Agdhefhe";
    char *accum = "";
    for(int i=0;i<=sizeof(*source)/sizeof(char);i++)
        {
            for(int j=0; j<i; j++)
            strcat(accum,source);
        }
        
    printf("%s",accum);
    return 0;
}

【问题讨论】:

  • 你认为accum指向的缓冲区中有多少额外字符空间?
  • 嗨 varkus,欢迎来到 stackoverflow。我认为@adrian-mole 的意思是您的accum 是一个指向内存中没有分配空间来保存您正在累积的字符串的位置的指针。你需要char *accum = malloc(...)
  • 我认为不是很多。有没有办法用指针来做,还是我需要指定数组的大小?
  • 哦,谢谢大家的帮助!
  • 循环的目的是什么?无论char 的宽度如何,sizeof(*source) 的定义为 1,sizeof(char) 的定义为 1。即使没有strcat 错误,这段代码也没什么意义。

标签: c string pointers char


【解决方案1】:

指针accum指向长度为1的常量初始化器。写入初始化器的数据区和超出分配空间的结果都是不确定的。

accum 必须指向一个可写区域,并分配了足够的空间来容纳最终的字符串。

【讨论】:

  • "" 不是constconst 是类型限定符,而不是表示内存是只读的形容词。由于单独的历史规则,而不是 const,C 标准未定义尝试修改字符串文字数组。
  • @EricPostpischil :我知道 - 这就是为什么写成 const 而不是 const。更改为 “常量”
【解决方案2】:

要做到这一点,您需要为目标分配足够的空间来写入。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char source[] = "Agdhefhe";
    size_t sz = 360;
    char *accum = (char *) malloc(sz + 1);
    *accum = '\0';  // needed for first strcat call
    for (int i = 0; i <= sizeof(*source) / sizeof(char); i++)
        for (int j = 0; j < i; j++)
            strncat(accum, source, sz);  // strncat used to not write too much

    printf("%s", accum);
    free(accum);
    return 0;
}

这个程序写成Agdhefhe,但可以简化为

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char const source[] = "Agdhefhe";
    size_t sz = 360;
    char *accum = (char *) malloc(sz + 1);
    *accum = '\0';  // needed for first strcat call
    strncat(accum, source, sz);

    printf("%s", accum);
    free(accum);
    return 0;
}

但是如果你想多次复制字符串:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char const source[] = "Agdhefhe";
    size_t sz = 360;
    char *accum = (char *) malloc(sz + 1);
    *accum = '\0';  // needed for first strcat call
    for (int i = 0; i <= sizeof(source) / sizeof(char); i++)  // the change is here
        for (int j = 0; j < i; j++)
            strncat(accum, source, sz);

    printf("%s", accum);
    free(accum);
    return 0;
}

这写AgdhefheAgdhefheAgdhefheAgdhefhe...Agdhefhe(360 个字符)。

【讨论】:

  • 361 个字符被写入,因为 nul 终止符也被写入 - 但你已经在代码中解释了这一点,所以这可能是一个迂腐的观点。然而问题是为什么它不起作用,而不是如何使它起作用。也可以将sz 设置为((sizeof(source) * (sizeof(source)+1)) / 2) * (sizeof(source) - 1)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-27
  • 1970-01-01
  • 2017-12-14
  • 2020-04-12
  • 2017-07-15
  • 1970-01-01
相关资源
最近更新 更多