额外\377已使用memcpy复制到缓冲区字符数组

额外\377已使用memcpy复制到缓冲区字符数组,c,C,我想读取一个文件(纯文本),看看它是否包含12字节的数据,以“CLOSE”开头,以“SCDH”结尾。我正在使用memcpy复制缓冲区字符串,以便比较连续的内存地址。但是,生成的缓冲区,buffer\u two在末尾有一个额外的\377。另一个变量buffer可以打印出CLOSE,如果传递的文件包含它。我不知道为什么我为buffer\u two得到了额外的字符 #include <stdio.h> #include <stdlib.h> #include <strin

我想读取一个文件(纯文本),看看它是否包含12字节的数据,以“CLOSE”开头,以“SCDH”结尾。我正在使用
memcpy
复制缓冲区字符串,以便比较连续的内存地址。但是,生成的缓冲区,
buffer\u two
在末尾有一个额外的
\377
。另一个变量
buffer
可以打印出
CLOSE
,如果传递的文件包含它。我不知道为什么我为
buffer\u two
得到了额外的字符

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

int main(int argc, char *argv[])  {
   FILE *f = fopen(argv[1], "r");
   int size;
   fseek(f, 0, SEEK_END);
   size = ftell(f);
   rewind(f);
   char *temp = malloc(sizeof(char) * size);
   fread(temp, sizeof(char), size, f);

   int i;
   for (i = 0; i < size - 12; ++i) {
      if (temp[i] == 'F') {
         char buffer[4];
         char buffer_two[4];
         memcpy(buffer, &temp[i], 4*sizeof(char));
         memcpy(buffer_two, &temp[i+8], 4*sizeof(char));
         printf("buffer %s\n", buffer);
         printf("buffer_two %s\n", buffer_two);

         if (memcmp(buffer, "CLOSE", 4) == 0 && memcmp(buffer_two, "SCDH", 4) ==0) {
            return 1;
         }

      }
   }

      return 0;
}

memcpy不会将“\0”附加到缓冲区,因此printf无法判断您视为字符串的内存块的结束位置。将终止“\0”添加到缓冲区:

char buffer[5];
...
buffer[4] = '\0';
或传入要打印的大小:

printf("buffer %.*s\n", 4, buffer);
您可以将
4*sizeof(char)
写成
4

sizeof应用于具有char、unsigned char或signed char类型的操作数时,(或 合格版本)结果为1。(C.5.3.3)


谢谢正如你所说,我能把它修好。我想这也适用于
memcmp
memcmp
是否将缓冲区与字符串进行比较作为字符串比较?我只想打印缓冲区,因为我想调试函数。我不需要缓冲区像字符串一样工作。我只需要复制4个字节,看看它们是否是我要找的。memcpy需要一个长度,只要两个字符串至少都有那么长,就行了。memcmp(缓冲区,“关闭”,4)看起来有误。要么省略E,要么确保缓冲区为5字节。另外,您的gdb输出没有错误,您只需要使用来使用
p*buffer@4
x/4c buffer
@chux,关键是sizeof(char)被定义为1。我在-Wall-Wextra-pedantic上没有收到任何关于使用memcpy(…,…,4)的警告,并且说cast是隐式的。你能更详细地说明你所关心的吗?在打印时,如果没有强制转换,就无法传递精度字段的大小?你说得对,但那和我说的正好相反。感谢您指出缺少的引号,并且我缺少格式字符串中的..@chux,谢谢您的澄清。
printf("buffer %.*s\n", 4, buffer);