在char数组中写入/读取int

时间:2014-11-07 18:40:22

标签: c arrays

我正在尝试编写一个程序,我可以将int复制到char数组中,然后使用char系统调用将write数组写入文件。在另一个程序中,我想将文件的内容读入char数组,然后从数组中检索int。我无法理解的是如何将int的内容写入数组以及如何从char数组中读取int

这就是我所拥有的

写入档案:

int fd2 = open("file2.txt", O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); 
//create buff2 with 1024 chars and last 4 bytes as int
write(fd2, buff2, 1028); 

我不确定如何准确实现注释行

从文件中读取:

int fd2 = open("file2.txt", O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); 
char buff2[1028];
read(fd2, buff2, 1028);
int val = *((int)((buff2+1023)+sizeof(int))); // file contains exactly 1028 bytes. first 1024 are characters, next 4 is int
printf("%d\n", val);

我尝试读取整数的行给出了编译错误invalid type argument of unary '*' (have 'int')

我将不胜感激任何帮助

2 个答案:

答案 0 :(得分:0)

编译错误本身可以使用int val = *(int*)(buff2+1024)轻松修复。

但是,如果您尝试从int中读取/写入一个不能被sizeof(int)整除的地址,那么您将得到错误的结果,或者更糟糕的是 - 记忆 - 访问违规。

也就是说,除非基础硬件架构以及手头的指定编译器支持未对齐的加载和存储操作(主要是)。

由于您不知道buff2的地址,因此您无法确定buff2+1024是否指向可被sizeof(int)整除的地址。因此,您必须一次读取/写入intchar

char* pVal = (char*)&val;

// Read 'int' on little-endian architecture
for (i=0; i<sizeof(val); i++)
    pVal[i] = buff2[1024+i];

// Read 'int' on big-endian architecture
for (i=0; i<sizeof(val); i++)
    pVal[sizeof(val)-1-i] = buff2[1024+i];

// Write 'int' on little-endian architecture
for (i=0; i<sizeof(val); i++)
    buff2[1024+i] = pVal[i];

// Write 'int' on big-endian architecture
for (i=0; i<sizeof(val); i++)
    buff2[1024+i] = pVal[sizeof(val)-1-i];

如果将buff2声明为全局变量,则可以强制编译器在对齐的内存地址处分配它。例如,假设您的平台上有sizeof(int) == 4

char buff[1028] __attribute__ ((aligned(4)));

然后,您可以安全地从{/ 1}中读取/写入任何可被int整除的偏移量:

sizeof(int)

答案 1 :(得分:0)

int val = *((int)((buff2+1023)+sizeof(int)));无法编译,因为它看起来像int val = *some_integer;,需要int val = *some_integer_pointer;

使用int val = *(int*)(buff2+1024)@barak manos的建议是一个很好的第一步。但它没有很好地处理内存对齐问题。

使用结构,而不是使用char*表示“前1024个是字符,接下来4是int”。

typedef struct AD93 {
  char ch[1024];
  int val; // or int32_t
} AD93_T;

AD93_T buff2;
write(fd2, &buff2, sizeof buff2);

read(fd2, &buff2, sizeof buff2);
printf("%d\n", buff2.val);