这是我正在使用的代码:
#include <stdio.h>
#include <stdlib.h>
void main(){
test = creat("TEST",0751);
close(test);
test = open("TEST",2);
write(test, "123456789101112131415",21);
lseek(test,-2,2);
read(test,swap_array,2);
write(test,swap_array,2);
lseek(test,-6, 1);
write(test,"xx",2);
}
这会创建一个8gb文件,而不是插入&#34; xx&#34;在我想要的数字之间。我的代码有什么问题?
答案 0 :(得分:3)
您未能包含相应的头文件。你应该至少包括:
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
此外,这将使您可以访问使代码可维护所需的符号常量。
以下是您的计划的工作版本:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
char swap_array[2];
int test = creat("TEST",0751);
close(test);
test = open("TEST",O_RDWR);
write(test, "123456789101112131415",21);
lseek(test,-2,SEEK_END);
read(test,swap_array,2);
write(test,swap_array,2);
lseek(test,-6, SEEK_CUR);
write(test,"xx",2);
return 0;
}
答案 1 :(得分:3)
您可能没有包含标题,因此范围内lseek()
可能没有原型,因此中间参数中的2
为int
,但lseek()
} {(1> long
)off_t
,你在64位机器上sizeof(int) != sizeof(long)
所以这两个2
被系统调用误解(可能将它们视为偏移量,无论出于何种原因,堆栈上剩下的内容被解释为SEEK_SET
或以其他方式跳转到较大的偏移量。)
基本上,您可能会将不准确的类型信息传递给系统调用,因为您没有包含正确的标头。经典(在POSIX干扰之前),中间2
将为2L
,因为l
中的lseek()
代表“长” - 在此之前,有{{1}使用普通seek()
(在16位int
类型的日子里) - 确保将int
作为lseek()
传递
需要。这些天,long
需要lseek()
;使用原型对于确保您编写的内容正确解释为off_t
。
在该描述中潜伏着很多UB,但是你没有使用off_t
等事实会引发警告标志。另外,为什么文件可执行?这看起来不像你正在编写的可执行代码。
此代码变体更加谨慎(并且不会在Mac OS X 10.11.6上使用GCC 6.2.0创建8 GiB文件)。
SEEK_SET
我使用#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#define MODE_0751 (S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH)
int main(void)
{
// All error checking omitted
char swap_array[2];
int test = creat("TEST", MODE_0751);
close(test);
test = open("TEST", O_RDWR);
write(test, "123456789101112131415", 21);
lseek(test, -2L, SEEK_END);
read(test, swap_array, 2);
write(test, swap_array, 2);
lseek(test, -6L, SEEK_CUR);
write(test, "xx", 2);
close(test);
return 0;
}
的(非常)旧习惯,但它们是可选的。各种2可以由L
(和sizeof(swap_array)
)替换。我很久以前就学会了C语言,八进制权限是开展业务的唯一方式; sizeof("xx")-1
和相关名称是未来几年。我发现一个4位或5位八进制数字比一串S_IRWXU
名称更易读。
确保使用选项集编译代码,以便在使用函数之前需要原型。例如,我使用:
S_Iwxyz