意外与写
创造巨大的文件,这是我使用的代码:意外与写
#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);
}
这将创建一个包含而不是插入的数字之间的“XX”我打算一个8GB的文件。代码有什么问题,因为我拥有它?
您未能包含适当的头文件。至少应包含以下内容:
#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;
}
我也会替换'creat'的标志... –
头文件解决了这个问题。我复制的旗帜严格为这个例子。 –
@EugeneSh。 'creat()'的规范标志或'open()'的第三个参数非常详细:['S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH'](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html)为'0751'。阅读八进制比标准更容易。 –
你可能不包括头,所以有可能是没有原型的范围lseek()
,所以中间参数的2
是int
,但lseek()
预计(一个)的long
off_t
,你是一个64位的机器,其中sizeof(int) != sizeof(long)
所以两个2
的是由系统调用误解的(也许他们当作偏移以任何理由还剩下些什么的堆栈是interp作为SEEK_SET
或以其他方式跳至大偏移量)。
基本上,你很可能不准确传递信息输入到系统呼叫,因为您还没有正确的头。经典(POSIX干预前),中间2
将2L
因为lseek()
的l
主张“长” - 在此之前,有一个seek()
历时一个普通int
(16位int
类型的天数) - 到确保long
通过lseek()
要求。这几天,lseek()
需要off_t
;使用原型对于确保您编写的内容正确解释为off_t
至关重要。
有很多UB的潜伏在这样的描述,但你不使用SEEK_SET
等事实提出了警告标志。另外,为什么该文件是可执行的?这看起来不像您正在编写的可执行代码。
代码的这种变体是更谨慎(并且不产生8吉布在Mac OS X 10.11.6文件,GCC 6.2.0)。
#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;
}
我使用L
的(非常)旧习惯,但它们是可选的。各种2可以替换为sizeof(swap_array)
(和sizeof("xx")-1
)。我在很久以前就学会了C,八进制许可是做生意的唯一途径; S_IRWXU
和相关的名字是未来的几年。我发现一个4位或5位八进制数字比一串S_Iwxyz
名称更易读。
确保您设定才可以使用函数原型所需的选项编译代码。例如,我使用:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition mx19.c -o mx19
$
由于您不显示您的'#include's,我们无法知道范围内的原型是什么。请提供一个简短的**完整**程序,说明您遇到的错误。有关更多信息,请参见[mcve]。 –
使用常量而不是幻数!为什么我们需要将它们翻译成任何有意义的东西? –