C - 使用定义表达式的 lseek 后读取错误
C - Wrong read after lseek with define expression
我有一个二进制文件,我需要从中读取时间戳。特别是,我正在尝试阅读最后一条记录。每条记录长 24 个字节,时间戳在前 8 个字节中。这是我写的代码:
#define IDX_RS_LEN (unsigned int)(sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
int offset;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -IDX_RS_LEN, SEEK_END);
read(fd, &rGmte, sizeof(unsigned long));
printf("offset:%d\trGmte: %lu\n", offset, rGmte);
} else {
printf("Error opening file\n");
}
close(fd);
return 0;
}
但这给了我以下输出:
offset:117384 rGmte: 0
这是错误的。如果我用固定值 24 替换定义中的表达式,我会得到正确的输出:
offset:117384 rGmte: 1606314900
另请注意,两种情况下的偏移量相同,但读取的值不同。
有什么想法吗?
您在 lseek
中使用了错误的类型来设置位置/偏移量,您应该使用 off_t
(signed long
) 而不是 unsigned int
。
看看What happens when I assign a negative value to an unsigned int?
设置为lseek
的偏移量应该是-24
:
printf("Output: %ld\n", -(signed long)(sizeof(unsigned long) * 3));
Output: -24
但你正在设置
printf("Output: %ld\n", -(unsigned int)(sizeof(unsigned long) * 3));
Output: 4294967272
切换自
#define IDX_RS_LEN (unsigned int)(sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
int offset;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -IDX_RS_LEN, SEEK_END);
到
#define IDX_RS_LEN (sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
off_t offset = IDX_RS_LEN;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -offset, SEEK_END);
它应该可以工作:https://godbolt.org/z/hEG4xx
我有一个二进制文件,我需要从中读取时间戳。特别是,我正在尝试阅读最后一条记录。每条记录长 24 个字节,时间戳在前 8 个字节中。这是我写的代码:
#define IDX_RS_LEN (unsigned int)(sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
int offset;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -IDX_RS_LEN, SEEK_END);
read(fd, &rGmte, sizeof(unsigned long));
printf("offset:%d\trGmte: %lu\n", offset, rGmte);
} else {
printf("Error opening file\n");
}
close(fd);
return 0;
}
但这给了我以下输出:
offset:117384 rGmte: 0
这是错误的。如果我用固定值 24 替换定义中的表达式,我会得到正确的输出:
offset:117384 rGmte: 1606314900
另请注意,两种情况下的偏移量相同,但读取的值不同。 有什么想法吗?
您在 lseek
中使用了错误的类型来设置位置/偏移量,您应该使用 off_t
(signed long
) 而不是 unsigned int
。
看看What happens when I assign a negative value to an unsigned int?
设置为lseek
的偏移量应该是-24
:
printf("Output: %ld\n", -(signed long)(sizeof(unsigned long) * 3));
Output: -24
但你正在设置
printf("Output: %ld\n", -(unsigned int)(sizeof(unsigned long) * 3));
Output: 4294967272
切换自
#define IDX_RS_LEN (unsigned int)(sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
int offset;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -IDX_RS_LEN, SEEK_END);
到
#define IDX_RS_LEN (sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
off_t offset = IDX_RS_LEN;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -offset, SEEK_END);
它应该可以工作:https://godbolt.org/z/hEG4xx