将字符串与memcpy连接时打印的奇怪字符

将字符串与memcpy连接时打印的奇怪字符,c,linux,C,Linux,我开发了此功能: bool execc(char *cmd, char *r) { FILE *fp; char t1[1024]; char *t2; memset(r, 0, sizeof(r)); fp = popen(cmd, "r"); if (fp == NULL) { return false; } t1 = r; while (fgets(t1, sizeof(t1), fp)

我开发了此功能:

bool execc(char *cmd, char *r)
{

    FILE *fp;
    char t1[1024];
    char *t2;
    memset(r, 0, sizeof(r));

    fp = popen(cmd, "r");
    if (fp == NULL)
    {
        return false;
    }
    t1 = r;

    while (fgets(t1, sizeof(t1), fp) != NULL)
    {
    r = &r[strlen(r)];
    memcpy(r, t1, strlen(t1));
    }
    r = t2;
    r[strlen(r)] = '\0';

    pclose(fp);

    return true;
}
int main()
{
    char r[4096];
    int i = 51;
    execc("ls -l /", r);
    printf("result of cmd: \n %s", r);
    return 0;
}
当我执行这个程序时,我得到了一些奇怪的字符,如下所示:

result of command: 
 total xxx
drwxr-xr-x   7   1001 root    4096 août  25 16:06 xxx
drwxr-xr-x   3 root   root    4096 juin  30 11:45 xxx
drwxr-xr-x   2 root   root   12288 oct.   9 15:26 bin
drwxr-xr-x   3 root   root    1024 août  28 11:48 boot
drwxr-xr-x   3 root   root    4096 août  26 10:51 boot-files
drwxrwxr-x   2 root   root    4096 janv. 12  2015 cdrom
drwxr-xr-x   7 xxxx xxxx  4096 juil. 14 16:43 data
drwxr-xr-x  20 root   root    4640 oct.  20 15:06 dev
drwxr-xr-x 174 root   root   12288 oct.   9 17:43 etc
drwxr-xr-x   5 root   root    4096 sept. 28 17:19 home
lrwxrwxrwx   1 root   root      33 août  26 10:50 initrd.img -> boot/initrd.img-xxxx-generic
lrwxrwxrwx   1 root   root      33 août  26 10:49 initrd.img.old -> boot/initrd.img-xxxx-generic
drwxr-xr-x  27 root   root    4096 avril 28 16:08 lib
drwxr-xr-x   2 root   root    4096 mai    7 17:35 lib32
drwxr-xr-x   2 root   root    4096 avril 28 15:33 lib64
drwx------   2 root   root   16384 janv. 12  2015 lost+found
drwxr-xr-x   3 root   root    4096 janv. 16  2015 media
drwxr-xr-x   2 root   root    4096 oct.  16  2014 mnt
drwxr-xr-x   7 root   root    4096 août  24 13:18 opt
dr-xr-xr-x 299 root   root       0 oct.  19 08:54 proc
drwx------  10 root   root    4096 oct.   5 18:03 root
drwxr-xr-x  27 root   root     940 oct.  20 14:38 run
drwxr-xr-x   2 root   root   12288 août  13 09:57 sbin
h�rwxr-xr-x   2 root   root    4096 oct.  22  2014 srv
dr-xr-xr-x  13 root   root       0 oct.  20 14:34 sys
drwxrwxrwx   2 nobody xxxx  4096 oct.  12 12:08 tftpboot
drwxrwxrwt  19 root   root   20480 oct.  20 15:30 tmp
drwxr-xr-x  12 root   root    4096 août  27 10:24 usr
drwxr-xr-x  14 root   root    4096 avril  7  2015 var
lrwxrwxrwx   1 root   root      30 août  26 10:46 vmlinuz -> boot/vmlinuz-xxxx-generic
3B�lrwxrwxrwx   1 root   root      30 août  13 10:01 vmlinuz.old -> boot/vmlinuz-xxxx-generic
如何修复此错误?我在线路上找不到问题

memcpy(r, t1, strlen(t1));
正在复制
t1
而不终止
\0
。所以这一行:

r[strlen(r)] = '\0';
无效,因为
strlen(r)
不会返回正确的值,因为
r
没有正确终止

如果
r
区域被零填充到整个操作范围内,它就可以工作。但事实并非如此

memset(r, 0, sizeof(r));
不会像您可能期望的那样工作
sizeof(r)
只是一个指针大小,大概是两个字节

线路

memcpy(r, t1, strlen(t1));
正在复制
t1
而不终止
\0
。所以这一行:

r[strlen(r)] = '\0';
无效,因为
strlen(r)
不会返回正确的值,因为
r
没有正确终止

如果
r
区域被零填充到整个操作范围内,它就可以工作。但事实并非如此

memset(r, 0, sizeof(r));
不会像您可能期望的那样工作
sizeof(r)
只是一个指针大小,大概是两个字节

sizeof(r)返回指针的大小要清空
r
最简单的方法是将main更改为具有

char r[4096] = ""; /* initialize to '\0' */
代码可能应该遍历读取的数据量,而不是缓冲区的溢出量

 memcpy(r, t1, strlen(t1));
 r = &r[strlen(t1)]; /* walk by amount added */
代码似乎被弄乱了

 t1 = r; /* << == doesn't compile */
在循环中尝试

 memcpy(r, t1, strlen(t1));
 r = &r[strlen(t1)]; /* walk by amount added */
 r[0] = '\0'; /* terminate the string */
一般来说,如果您获得的数据超过4k,就会发生不好的事情

bool execc(char *cmd, char *r)
{

   FILE *fp;
   char t1[1024];

   fp = popen(cmd, "r");
   if (fp == NULL)
   {
      return false;
   }

   while (fgets(t1, sizeof(t1), fp) != NULL)
   {
      memcpy(r, t1, strlen(t1));
      r = &r[strlen(t1)]; /* walk by amount added */
      r[0] = '\0'; /* terminate the string */
   }
   pclose(fp);

   return true;
}
sizeof(r)
返回指针的大小清空
r
最简单的方法是将main更改为具有

char r[4096] = ""; /* initialize to '\0' */
代码可能应该遍历读取的数据量,而不是缓冲区的溢出量

 memcpy(r, t1, strlen(t1));
 r = &r[strlen(t1)]; /* walk by amount added */
代码似乎被弄乱了

 t1 = r; /* << == doesn't compile */
在循环中尝试

 memcpy(r, t1, strlen(t1));
 r = &r[strlen(t1)]; /* walk by amount added */
 r[0] = '\0'; /* terminate the string */
一般来说,如果您获得的数据超过4k,就会发生不好的事情

bool execc(char *cmd, char *r)
{

   FILE *fp;
   char t1[1024];

   fp = popen(cmd, "r");
   if (fp == NULL)
   {
      return false;
   }

   while (fgets(t1, sizeof(t1), fp) != NULL)
   {
      memcpy(r, t1, strlen(t1));
      r = &r[strlen(t1)]; /* walk by amount added */
      r[0] = '\0'; /* terminate the string */
   }
   pclose(fp);

   return true;
}

为了获得超过4k的数据,我做了如下重大修改:

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

bool execc(char *cmd, char **value)
{
    FILE *fp;
    char buffer[128];
    char *tmp;
    int size;

    fp = popen(cmd, "r");
    if (fp == NULL)
    {
        return false;
    }
    while (size = fread (buffer,1,sizeof(buffer),fp))
    {
        buffer[size] = '\0';        
        if(*value == NULL)
        {
            *value = strdup(buffer);    
        }
        else
        {   
            tmp = *value;           
            *value = (char*)calloc(strlen(tmp)+strlen(buffer), sizeof(char));   
            memcpy(*value, tmp, strlen(tmp));
            memcpy(*value+strlen(tmp), buffer, strlen(buffer));
            free(tmp);
        }
    }
    pclose(fp);

    return true;
}

int main()
{
    char *r = NULL;
    execc("ls -l /", &r);
    if(r!= NULL)
    {   
        printf("result of cmd: \n %s", r);
        free(r);
    }
    return 0;
}
#包括
#包括
#包括
#包括
bool EXEC(字符*cmd,字符**值)
{
文件*fp;
字符缓冲区[128];
char*tmp;
整数大小;
fp=popen(cmd,“r”);
如果(fp==NULL)
{
返回false;
}
而(size=fread(buffer,1,sizeof(buffer,fp))
{
缓冲区[大小]='\0';
如果(*值==NULL)
{
*值=strdup(缓冲区);
}
其他的
{   
tmp=*值;
*value=(char*)calloc(strlen(tmp)+strlen(buffer),sizeof(char));
memcpy(*值,tmp,strlen(tmp));
memcpy(*值+strlen(tmp),缓冲区,strlen(缓冲区));
免费(tmp);
}
}
pclose(fp);
返回true;
}
int main()
{
char*r=NULL;
execc(“ls-l/”、&r);
如果(r!=NULL)
{   
printf(“命令的结果:\n%s”,r);
自由(r);
}
返回0;
}

为了获得超过4k的数据,我做了如下重大修改:

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

bool execc(char *cmd, char **value)
{
    FILE *fp;
    char buffer[128];
    char *tmp;
    int size;

    fp = popen(cmd, "r");
    if (fp == NULL)
    {
        return false;
    }
    while (size = fread (buffer,1,sizeof(buffer),fp))
    {
        buffer[size] = '\0';        
        if(*value == NULL)
        {
            *value = strdup(buffer);    
        }
        else
        {   
            tmp = *value;           
            *value = (char*)calloc(strlen(tmp)+strlen(buffer), sizeof(char));   
            memcpy(*value, tmp, strlen(tmp));
            memcpy(*value+strlen(tmp), buffer, strlen(buffer));
            free(tmp);
        }
    }
    pclose(fp);

    return true;
}

int main()
{
    char *r = NULL;
    execc("ls -l /", &r);
    if(r!= NULL)
    {   
        printf("result of cmd: \n %s", r);
        free(r);
    }
    return 0;
}
#包括
#包括
#包括
#包括
bool EXEC(字符*cmd,字符**值)
{
文件*fp;
字符缓冲区[128];
char*tmp;
整数大小;
fp=popen(cmd,“r”);
如果(fp==NULL)
{
返回false;
}
而(size=fread(buffer,1,sizeof(buffer,fp))
{
缓冲区[大小]='\0';
如果(*值==NULL)
{
*值=strdup(缓冲区);
}
其他的
{   
tmp=*值;
*value=(char*)calloc(strlen(tmp)+strlen(buffer),sizeof(char));
memcpy(*值,tmp,strlen(tmp));
memcpy(*值+strlen(tmp),缓冲区,strlen(缓冲区));
免费(tmp);
}
}
pclose(fp);
返回true;
}
int main()
{
char*r=NULL;
execc(“ls-l/”、&r);
如果(r!=NULL)
{   
printf(“命令的结果:\n%s”,r);
自由(r);
}
返回0;
}

'memset(r,0,sizeof(r));'不做你认为它做的事…即使它做了,也是货物缓冲区清理。程序甚至不编译。我不知道为什么我要麻烦,但无论如何。。。添加更多临时变量以保存中间结果,例如“bufLen=sizeof(r);”。关闭优化,使用调试器。我已经修复了错误,只需重新放置
memcpy(r,t1,strlen(t1))
memcpy(r,t1,sizeof(t1))'memset(r,0,sizeof(r));'不做你认为它做的事…即使它做了,也是货物缓冲区清理。程序甚至不编译。我不知道为什么我要麻烦,但无论如何。。。添加更多临时变量以保存中间结果,例如“bufLen=sizeof(r);”。关闭优化,使用调试器。我已经修复了错误,只需重新放置
memcpy(r,t1,strlen(t1))
memcpy(r,t1,sizeof(t1))我已经解决了数据大小的问题,您可以看到我的后续响应我已经解决了数据大小的问题,您可以看到我的后续响应