使用 strcpy 时如何将空终止符添加到 char 指针

How to add null terminator to char pointer, when using strcpy

我有一个程序正在尝试使用 strcpy() 函数。我知道当一个人使用 char 数组时,例如:char array[10] 空终止符可以设置为:array[0] = '[=13=]'; 但是,在使用 char 指针时我将如何设置空终止符?

编辑:程序编译,但输出垃圾

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

int main(void)
{
    char *target;
    char *src = "Test";

    target = malloc(sizeof(char));
    src = malloc(sizeof(char));

     strcpy(target,src);
     printf("%c\n",target); 

    return 0;
}

你不需要。 strcpy() 的第二个参数需要 nul 终止,第一个参数需要符合源中的字符数 + nul 终止符。

您的代码中存在的问题是:

  1. 您以错误的方式使用了 sizeof 运算符,您正在通过再次分配内存覆盖 src 指针。

    要获得字符串的长度,您需要 strlen() 而您不需要在每个指针上调用 malloc()

    因为src指向新分配的space,因为

    ,所以你正在从未初始化的数据中复制,所以你得到了垃圾值
    src = malloc(sizeof(char));
    

    你不应该那样做。

  2. sizeof(char) == 1 根据定义,所以您只为 1 个字节分配 space,如果它是一个有效的 C 字符串,则必须是 '[=21= ]' 因为只有 1 个字符的空间。

  3. 字符串的正确 printf() 说明符是 "%s",您使用的 "%c" 是一个字符。

正确的做法是

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

int main(void)
{
    char       *target;
    const char *src;

    src    = "Test"; /* point to a static string literal */
    target = malloc(1 + strlen(src)); /* allocate space for the copy of the string */
    if (target == NULL) /* check that nothing special happened to prevent tragedy  */
        return -1;

    strcpy(target, src);
    printf("%s\n", target);
    /* don't forget to free the malloced pointer */
    free(target);

    return 0;
}
target = malloc(10);

具有容纳字符串和 nul 终止符的内存。我不明白为什么要为 src 分配内存,因为我看到您使用的是字符串文字。只需为目标分配足够的内存,然后 strcpy() 确保您没有越界写入数组。

正确的方法是

target = malloc((strlen(src) + 1));

记下当你这样做的时候

char *src = "Test";

字符串"Test"存储在一个只读位置,这个位置的地址返回给src。因此,您的字符串已经在内存中,无需为此再次分配内存,而您正在尝试这样做并且做错了。所以为 src

去掉 malloc()

在您的代码中

strcpy(target,src);

src 不是空终止的。这会调用未定义的行为。

此外,通过使用 malloc(sizeof(char));,您可以为单个 char 元素分配内存。这是可能你不想要的。

接下来,根据strcpy()man page,(强调我的)

The strcpy() function copies the string pointed to by src, including the terminating null byte ('[=17=]') to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy.

所以,只要

  1. 您的来源是一个正确的以 null 结尾的字符数组 (string)
  2. 目标有足够的内存来保存源的内容

你可以开始了。所以,你必须

  1. null 终止 src 数组。
  2. target 分配足够的内存,以便它可以容纳 src 的内容。

最后,要提一下,一旦你使用了一个字符串,你应该使用 %s 格式说明符和 printf() 来打印字符串。

man strcpy

DESCRIPTION
The strcpy() function copies the string pointed to by src, including the terminating null byte ('[=12=]'), to the buffer pointed to by dest.

因此,如果 src 已经有空终止字节,则您不必添加它。

BUGS
If the destination string of a strcpy() is not large enough, then anything might happen.

所以 :

char *src = "Test"; //  4 chars + '[=11=]'
target = malloc(sizeof(char)); // Space for 1 char
 strcpy(target,src); // Woops !

Sourav Ghosh 的回答是正确的,但对于这种特定情况,您应该使用 strdup(),因为它会为您处理内存分配和复制:

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

int main(void)
{
    const char *src = "Test";   // You should make this const
    char *target = strdup(src); // Duplicate             
    if (target == NULL) {       // Check
        return EXIT_FAILURE;
    }
    printf("%s\n", target);
    return EXIT_SUCCESS;
}   

到目前为止,答案解决了您代码中的缺陷和您明显的误解,而不是您的问题。指向内存的指针可以像数组一样被索引,所以给定:

char *target = malloc( 10 ) ;

可以这样设置元素:

target[0] = '[=11=]' ;