为什么我不能使用strcpy函数?

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

int main() {
   const char* hello = "Hello, World!";
   char *str = malloc(14 * sizeof(char));

   for (int i = 0; i < 14; i++) {
      strcpy(str[i],hello[i]);
   }
   str[14]='\0';

   printf("%s\n", str);

   return 0;
}

编译警告:

警告:传递给 'strcpy' 的第 1 个参数使指针从整数转换而来,没有强制类型转换 [-Wint-conversion]   
注释:期望的是 'char *' 类型,但实参是 'char' 类型   
警告:传递给 'strcpy' 的第 2 个参数使指针从整数转换而来,没有强制类型转换 [-Wint-conversion]

str 是一个指针,hello 也是,发生了什么事情?


9
str[i]hello[i]都不是指针,它们都是字符。下一个问题是str[14]超出了分配的内存范围--你只分配了14个字节,有效索引从0到13。 - Paul Hankin
3
str是一个指针,而str[i]不是。 - tkausl
6
strcpy(str, hello) 是正确的调用方式。 - Paul Hankin
1
... 不使用循环结构 - John Bollinger
1
@PaulHankin strdup 不是标准函数。 - Jabberwocky
显示剩余3条评论
3个回答

6
你做错了:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main() {
   const char* hello = "Hello, World!";
   char *str = malloc(strlen(hello)+1);

   strcpy(str,hello);
   printf("%s\n", str);
   free(str);
   return 0;
}

说明: strcpy操作的是指针,两者都是写入和读取的起始位置,因此必须传递这些指针,而不是字符。你的读取位置是hello,写入位置是str。然后,strcpy会循环查找0字符(包括它),以停止复制,因此你的循环是不必要的。最后一件事是你必须释放分配的内存。另外,sizeof(char)没有意义:它总是1。

您提供了一种正确的实现方式,但如果它还能解释为什么 OP 的代码是错误的以及错误信息的含义,那么这将是一个更好的答案。 - John Bollinger
同意刚刚添加的内容,也许这会有助于理解问题。 - Mateusz Wojtczak

2
问题在于你试图将C字符串作为字符数组使用,尽管这是允许的,但与将它们作为指向以空字符结尾的字符串的指针使用不同。执行`hello[0]`将计算出字符串的第一个字符,它只是通常为8位整数的值。`char`是一个值,它不对应于内存地址。
正确的语句应该是:
strcpy(str, hello);

作为参考,如果您想获取从字符串某一点开始的子字符串,可以执行以下操作

strcpy(str, hello + 1);

在指针上执行加法运算会得到一个指向内存中某个地址向前n个地址的指针。

你可能想要删除指针算术的引用 - 这可能不是这个答案的主题,而且可能会普遍造成困惑。 - anatolyg
我已经删除了它,但我认为提问者试图通过在接受指针的函数中错误地执行str[i]来获取字符串起始点的第i个位置。 - Josh Weinstein
hello[0] 评估一个 char,通常是8位(但可能不是),可以是有符号或无符号的。只有一些char是可打印字符(具体来说,对于isprint(c)返回非零值的非负字符)。我认为你的答案在精神上是正确的,但这些小的技术错误会降低它的质量。 - Paul Hankin
@PaulHankin 很好的观点,我修正了一下,只是为了澄清 char 是一个值,而不是内存地址或指针。 - Josh Weinstein

0

strcpy的定义需要两个char指针,而不是str[]hello[]数组。

char *strcpy(char *destination, const char *source)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接