linux系统编程之文件IO案例题

给出一个文件文件,删除该文本的第10行

#include
#include
#include
#include
#include
#include
/*                         面试题要求:                                                     */
/*                  编写一个程序,删除一个文件的第10行*/

//__getline() 传入文件指针 统计行数
size_t __getline(FILE* fp)
{
    if(fp == NULL)  return 0;
    int linecount =  0;
    int  res = 0;
    rewind(fp);
    while((res = fgetc(fp)) != EOF)
    {
        if(res == '\n')
            linecount++;
    }
    return linecount;
}


//getlinehcar(int fd) 传入一个文件路径  打开文件 获取第n行有多少字符 返回字符数量
size_t getlinechar(char* pathname,size_t n)
{
    size_t count = 0;
    FILE* fp = NULL;//文件指针
    int res = 0;
    //参数检测
    if(pathname == NULL)
    {
        fprintf(stderr,"getlinechar::无效路径");
        return -1;
    }
    if(n <= 0)  return 0;
    //打开文件
    fp = fopen(pathname,"r");
    if(fp == NULL)
    {
        perror("getlinechar:");
        return -1;
    }
    size_t tempcount = __getline(fp);
    //n = n > __getline(fp) ? __getline(fp) : n;
    n = n > tempcount ? tempcount : n;
//    printf("getlinechar: n = %zu\n",n);
    rewind(fp);
    //读取n行中的字符个数
    while((res = fgetc(fp)) != EOF &&  n > 0)
    {
        if(res == '\n')
            n--;
        count++;
    }
    fclose(fp);
//    printf("count = %zu\n",count);
    return count;
}

int main(int argc,char* argv[])
{
    //使用getline()函数获取第十行
    if(argc < 2)
    {
        fprintf(stderr,"参数不正确\n");
        return -1;
    }
    //size_t n = (size_t)atoi(argv[2]);
    //printf("第%zu行一共有%zu字节\n",n,getlinechar(argv[1],n));
    int fdread = 0;
    int fdwrite  = 0;
    //打开文件
    fdread = open(argv[1],O_RDONLY);//从第11行开始读
    if(fdread <=  0)
    {
        perror("main::fdread::open:");
        return -1;
    }
    fdwrite = open(argv[1],O_RDWR | O_EXCL);//从第10行开始写
    if(fdwrite <= 0)
    {
        close(fdread);
        perror("main::fwrite::open");
        return -1;
    }
    //获取读文件偏移 即第11行偏移
    size_t readpos = getlinechar(argv[1],11);
//    printf("readpos = %zu\n",readpos);    
    //移动文件指针到第11行
    if(0 > lseek(fdread,readpos,SEEK_SET))
    {
        perror("main::read::lseek:");
        close(fdread);
        close(fdwrite);
        return -1;
    }
    //获取写文件偏移
    size_t writepos = getlinechar(argv[1],10);
    //printf("writepos:%zu",writepos);
    //移动到第10行
    if(0 > lseek(fdwrite,writepos,SEEK_SET))
    {
        perror("main::write::lseek:");
        close(fdread);
        close(fdwrite);
    }
    int len = 0;
    int res = 0;
    int pos = 0;
    char buf[1024] = { 0 };
    //读fdread 写fwrite
    while(1)
    {
        len = read(fdread,buf,sizeof(buf));
        //出错退出
        if(len < 0)
        {
            perror("main::read:");
            break;
        }
        //文件末尾退出
        if(len == 0)    break;
        pos = 0;
        while(len > 0)
        {
            res = write(fdwrite,buf+pos,len);
            if(res < 0)
            {
                perror("main::write:");
                close(fdread);
                close(fdwrite);
                exit(1);
            }
            pos += res;//断点
            len -= res;
        }
    }
    //截断字节 = 源文件总长度 - 第10行长度
    //回到文件头
    lseek(fdwrite,0,SEEK_SET);
    off_t trunclen = lseek(fdwrite,0,SEEK_END) - readpos + writepos;
//    printf("%zu\n",trunclen);
    ftruncate(fdwrite,trunclen);
    close(fdread);
    close(fdwrite);
    return 0;
}

#程序运行前:
linux系统编程之文件IO案例题_第1张图片
#程序运行后:
linux系统编程之文件IO案例题_第2张图片
实现原理
linux系统编程之文件IO案例题_第3张图片

你可能感兴趣的:(linux系统编程)