无法在C中复制字符串?

时间:2012-08-27 17:30:27

标签: c pointers

我正在尝试将String的char指针复制到另一个?

我尝试了下面给出的代码。编译成功但输出为空(无输出)。

a)我哪里错了?我的编程逻辑失败了?

b)如何改进此代码以获得所需的输出?

    void main()
    {
     char *p="krishna";
     char *q;

      while(*p!='\0')
      {
       *q++=*p++;
      }
      printf("%s",q);
      getch();
    }

10 个答案:

答案 0 :(得分:3)

void main()
{
  char *p="krishna";
  char *q;

  /* When copying, you modify your pointers, so you need another one
  ** to store where your string is starting. */
  char *r;

  /* Until now, q points to nowhere.
  ** You need to allocate the place it should point: */
  r = q = malloc(strlen(p) + 1);
  /* Plus 1 because C string uses one extra character in the end,
  ** the NULL ('\0') character. */

  while(*p!='\0')
  {
   *q++=*p++;
  }

  /* Until now, you've copied every character, except the NULL char at the end.
  ** you must set it in order for it to be a valid string. */
  *q = '\0';

  /* Now q points to the last (NULL) character of the string.
  ** In order to print it, you will need a pointer to the start of the string,
  ** that is why we need r: */
  printf("%s",r);

  /* When you are done using a memory buffer you allocated yourself,
  ** you must free it so it can be reused elsewhere. */
  free(r);

  getch();
}

答案 1 :(得分:2)

  

a)我哪里错了?我的编程逻辑失败了?

嗯,你做错了几件事。例如,void main是非标准的; main的返回类型应为int

话虽这么说,你正在寻找的真正的问题与q未初始化的事实有关,但你仍试图通过它复制到内存(这是未定义的行为)。要解决此问题,请尝试分配q,例如

char *q = malloc(8);

请注意,您必须稍后注意free此处分配的内存。

除此之外,您还忘记复制NUL终止符。

*q = 0;

...复制循环后...在递增指针后也会打印q,因此在printf调用之前它将不再位于字符串的开头。您应该将头部的副本存储在另一个变量中。另外,请小心使用没有任何换行的普通printf,因为流可以缓冲,因此可以保持未刷新状态 - 使用明确的fflush(stdout);


  

b)如何改进此代码以获得所需的输出?

嗯,我能想到的第一个最直接的改进是使用strcpy

#include <stdio.h>

main() {
  const char p[] = "krishna";
  char q[sizeof p];
  strcpy(q, p);
  puts(q);
  getchar();
  return 0;
}

答案 2 :(得分:1)

你应该为'q'分配内存以保存复制的字符串。

答案 3 :(得分:1)

你并没有说你想要多少内存,所以,你正试图跑过别人的记忆。因此,使用malloc或数组。

答案 4 :(得分:1)

你需要在q的末尾添加一个'\0'字符。你还需要为它分配足够的内存。

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

int main()
{
  char *p="krishna";
  int size = strlen(p) + 1;
  char *q = (char *) malloc(size);
  char *qi = q;

  do
  {
   *q++=*p;
  } while(*p++!='\0');

  q = qi; //reset q to the beginning of the string

  printf("%s",q);
  getch();
  return 0;
}

我认为这应该有用

答案 5 :(得分:1)

您正在使用for循环移动指针。此外,您应该为q分配内存。

试试这个:

void main()
{
 char *p="krishna";
 char *q = malloc(sizeof(char) * 20);
 char *temp = NULL;

 /* save q */
 temp = q;
  while(*p!='\0')
  {
   *q++=*p++;
  }
  /* reset saved q */
  q=temp;
  printf("%s",q);
  getch();
}

答案 6 :(得分:1)

a)您移动q但不要将其重置为字符串的开头。

正如许多其他人所指出的那样,你还需要复制操作的目的地是分配内存的地方,在char *buf = malloc(BUF_SIZE)的堆上或在char buf[BUF_SIZE]的堆栈上。

最后,目的地必须为零终止。

b)使用专用API通常更具可读性,并且可以更好地执行自制的循环。

答案 7 :(得分:1)

在您提供的这个示例中,您没有为新的字符数组分配内存,而是将字符复制到未知缓冲区中。这可能会导致各种问题(阅读缓冲区溢出和攻击)。此外,一旦完成将字符复制到未知缓冲区,此缓冲区不再指向字符串的开头,而是指向字符串的结尾。如果您的想法是将字符数组复制为C中的字符串,则可以使用以下代码执行此操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
  char *p="krishna";
  char *q = (char*) malloc(sizeof(char) * (strlen(p) + 1));

  strcpy(q, p);

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

在大多数情况下,数组末尾的空字符('\ 0')的额外字节是不必要的,但它是为了正确而包含的,因为字符数组应该由NULL字符结束分隔。

通过使用malloc,您为我们正在复制字符串的缓冲区分配(动态)内存。无论何时动态分配内存,它也应该稍后释放,否则将继续使用它。为了释放malloc的这种使用,在应用程序返回之前,最后使用'free'命令。

答案 8 :(得分:0)

一个重要的改进建议,但尚未找到(其他人已经指出了与字符串相关的问题)

Your declaration of main is not correct. 
The return value should  not be  void  but int

答案 9 :(得分:0)

许多人告诉我将q的值初始化为内存地址。我认为没有必要这样做。因为这段代码在未定义的行为中正常工作。

 int main()
 {
 char *p="krishna";
 char *q,*r;
 r=q;

  while(*p!='\0')
  {
   *q++=*p++;
  }
   *q='\0';
    q=r;
  printf("%s",q);
  getch();
  return 0;
 }