思路:

1.在一个进程中open()打开文件,因为每一行的结尾是’\n’,所以我们可以将文件指针定位到文件的第11行,将后面的数据read()拷贝到一个数组中,再重新定位文件内指针到第十行,写入我刚刚存储数据的数组,读取文件当前指针,最后使用ftruncate()截断文件。
2.在一个进程中open()打开两次文件,一次只读,一次读写,只读文件指针定位到第十一行,读写文件指针定位到文件第十行,将只读文件指针后面的数据依次read()拷贝write()写入到读写文件指针后面,最后fruncate()截断读写文件指针后面的内容。

代码

我使用的是第二种方法,思路好理解:

#include <sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char **argv)
{
	int fd1,fd2;
	int rpos = 0, wpos = 0,pos = 0;//读取位置,写入位置,当前位置
	char str[2];                   //临时数组
	int row = 0;                   //行数判断
	int trun_num =0 ;              //需要截断的位置
	//如果传入参数不够,给出提示
	if(argc < 2) {
		printf("Usage...\n");
		exit(1);
	}
	//只读方式打开
	fd1 = open(argv[1],O_RDONLY);
	if(-1 == fd1){
		perror("open()");
		exit(1);
	}
	//以读写方式打开
	fd2 = open(argv[1],O_RDWR);
	if(-1 == fd2){
		perror("open()");
		exit(1);
	}
	//找到读取位置
	while(1){
		if(row == 10) {
			rpos = pos;
			break;
		}
		if(read(fd1,str,1) <= 0) break;
		//printf("%s\n",str);
		if(str[0] == '\n') row = row+1;//判断是否到了一行的截止
		pos = pos + 1;
	}
	pos = 0;
	row = 0;
	//找到写入位置
	while(1){
        if(row == 9) {
            wpos = pos;
            break;
        }
        if(read(fd2,str,1) <= 0) break;
        if(str[0] == '\n') row = row+1;//判断是否到了一行的截止
        pos = pos + 1;
	}
	//读取数据写入文件
	while(1){
		if(read(fd1,str,1)<= 0) break;
		write(fd2,str,1);

	}
	//从写入位置开始截断
	trun_num = lseek(fd2,0,SEEK_CUR);
	ftruncate(fd2,trun_num);	
	close(fd1);//关闭文件
	close(fd2);
	exit(0);
}

总结

以上代码已经可以实现删除一个文件的第十行,就是有一点繁琐,可以先找到写入位置,再找读取位置,这样就更简单了。