【问题标题】:Evaluate Linux file copy command in c在 c 中评估 Linux 文件复制命令
【发布时间】:2016-12-01 10:05:49
【问题描述】:

我有下面的程序,它将一个的整个文本文件复制到另一个您输入源文件和目标文件的名称的地方。我需要修改我的程序来评估 Linux cp 命令。

我的subcopy 命令会将源文件的名称、目标文件的名称以及开始行和结束行 将复制到目标文件的源文件行,如下例所示:

subcopy.o Sourcefile.txt 目标文件.txt 100 200

从 Sourcefile.txt 复制第 100 - 200 行到destinationfile.txt

已编辑:我已经完成了所有艰苦的工作。剩下的就是选择我想从一个文件复制到另一个文件的行数。请注意该示例的工作原理。

    #include <stdio.h>
#include <stdlib.h>
 
 
 void cp(char source_file[],char destination_file[],int lines_copy)
 {
      
      char ch;
   FILE *source, *destination;
 
  
   
 
   source = fopen(source_file, "r");
 
   if( source == NULL )
   {
      printf("File name not found, make sure the source file exists and is ending at .txt\n");
      exit(EXIT_FAILURE);
   }
 
   
 
   destination = fopen(destination_file, "w" );
 
   if( destination == NULL )
   {
      fclose(source);
      printf("Press any key to exit...\n");
      exit(EXIT_FAILURE);
   }
 
   while( ( ch = fgetc(source) ) != EOF )
      fputc(ch, destination);
 
   printf("Copied lines %d  from %s to %s \n",lines_copy,source_file,destination_file,".txt");
 
   fclose(source);
   fclose(destination);

 }
 
int main()
{


    char s[20];
    char d[20];
    int lines;
    
    printf("-Enter the name of the source file ending in .txt\n-Enter the name of the destination file ending in .txt\n-Enter the number of lines you want to copy\n\n");
            
     printf(">subcopy.o ");
    gets(s);
       printf("destination file-> ");
        gets(d);
        printf("Lines: ");
        scanf("%d",&lines);
      
    cp(s,d,lines);
    
    
    
    
    
    
    
    return 0;
    
 }

【问题讨论】:

标签: c linux file-io cp


【解决方案1】:

Mmap 文件并搜索特定行号的偏移量。由于映射文件确实是内存,因此一旦找到偏移量就没有额外的存储过程。 我写了一个小代码来获取行号。您必须修改将数据复制到目标文件的代码。

#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <err.h>

/* following code assumes all file operations succeed. In practice,
 * return codes from open, close, fstat, mmap, munmap all need to be
 * checked for error.
*/
int read_file_line(const char *path, int line_no)
{
    struct stat s;
    char *buf;
    off_t start = -1, end = -1;
    size_t i;
    int ln, fd, ret = 1;

    if (line_no == 1) start = 0;
    else if (line_no < 1){
        warn("line_no too small");
        return 0; /* line_no starts at 1; less is error */
    }

    line_no--; /* back to zero based, easier */

    fd = open(path, O_RDONLY);
    fstat(fd, &s);

    buf = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

    /* optional; if the file is large, tell OS to read ahead */
    madvise(buf, s.st_size, MADV_SEQUENTIAL);

    for (i = ln = 0; i < s.st_size && ln <= line_no; i++) {
        if (buf[i] != '\n') continue;

        if (++ln == line_no) start = i + 1;
        else if (ln == line_no + 1) end = i + 1;
    }

    if (start >= s.st_size || start < 0) {
        warn("file does not have line %d", line_no + 1);
        ret = 0;
    } else {
        /*  Do Copy data from this block into destination */
    }

    munmap(buf, s.st_size);
    close(fd);

    return ret;
}

【讨论】:

  • 使用 seek 命令到 100 位置。 有问题的命令按行工作,而不是字节。您不能寻求 byte 偏移量并期望匹配行。
  • @AndrewHenle 感谢纠正我,我已经编辑了我的帖子。甚至我写了一个简单的代码来查找文件中的行号。
【解决方案2】:

为什么要编写一个程序来做到这一点?你可以用一个简单的 bash 命令来做到这一点:

SOURCE=/path/to/source/file
DEST=/path/to/dest/file
START=100
END=200

tail -n +$START $SOURCE | head -n $(( $END - $START )) > $DEST

【讨论】:

  • 你能说得更具体点吗?
  • 我想在 c m8 中做到这一点
  • 你不需要在 C 中这样做;您可以使用标准命令。
  • 为什么你想用 C 来做这个?
  • 因为我不是为我这样做的:)
猜你喜欢
  • 2015-12-12
  • 2021-06-07
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多