如何读取文本文档的特定行并将它们写入另一个文本 | C

how to read specific lines of a text document and write them to another text | C

我创建了一个函数,它将源文件的名称、目标文件的名称以及将复制到目标文件的源文件行的开头和结尾行作为参数,例如下面的例子。我想要做的就是输入我想复制到另一个文本文件的行,如下例所示:

我向您展示的代码只是 "reads" 一个文本文件的内容和 "writes" 另一个文本文件的内容。我想要 "write" 用户给出的特定行,而不是整个文本文件

Inputs by the user:
Source_file.txt //the file that the destination file will read from
destination_file.txt //the new file that the program has written
2 3 // the lines that it will print to the destination file: 2-3

Source_file.txt:

1
2
3
4
5
6

destination_file.txt

2
3

代码:

#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;
}

在 cp() 中,为了 select 要保留的行,您必须知道它们在输入文件中的位置。因此,您需要计算行数。

使用 fgets 而不是 fgetc 将允许您计算行数。


另一方面,如果我想在文件中 select 行 3 和 7 到 12,我会使用:

sed -n -e "3p;7,12p" < input.txt > output.txt

这是一个非常简单的解决方案,为了简单起见,假设您知道一行的最大长度为 100 个字符(如果一行超过 100 个字符,则只取前 100 个字符)

在顶部(main 之外)你可以写

#ifndef MAX_LINE_SIZE
#define MAX_LINE_SIZE 100
#endif

我知道很多人不喜欢这个,但我认为在这种情况下,如果您需要修改最大行大小,它会使代码更优雅并且更容易更改。

要只打印需要的行,您可以这样做

char line[MAX_LINE_SIZE];

int count = 0;

while (fgets(line, MAX_LINE_SIZE, source)){
    count++;
    if (3 <= count && count <= 5){
        fputs(line, destination);
    }
}

while 循环将在 EOF 重新加载时结束,因为 fgets returns NULL.

P.S。可能会有一些小错误,因为我写得很快并且靠记忆,但总的来说它应该可以工作。

你的程序有一些问题:

  • 不要使用gets(),可能会造成缓冲区溢出

  • 始终使用类型 int 来存储 fgetc() 的 return 值,以便将 EOF 与常规字节值区分开来。

  • 您向 printf() 传递了一个额外的参数 ".txt"。它将被忽略,但仍应删除。

要将一系列行从源复制到目标,您可以这样修改您的函数:

#include <stdio.h>
#include <string.h>
#include <errno.h>

void cp(char source_file[], char destination_file[], int start_line, int end_line) {
    int ch;
    int line = 1, lines_copied;
    FILE *source, *destination;

    source = fopen(source_file, "r");
    if (source == NULL) {
        printf("Cannot open input file %s: %s\n",
               source_file, strerror(errno));
        exit(EXIT_FAILURE);
    }

    destination = fopen(destination_file, "w");
    if (destination == NULL) {
        printf("Cannot open output file %s: %s\n",
               destination_file, strerror(errno));
        fclose(source);
        exit(EXIT_FAILURE);
    }

    while ((ch = fgetc(source)) != EOF) {
        if (line >= start_line && line <= end_line) {
            fputc(ch, destination);
        }
        if (ch == '\n') {
            line++;
        }
    }
    lines_copied = 0;
    if (line > start_line) {
        if (line >= end_line) {
            lines_copied = end_line - start_line + 1;
        } else {
            lines_copied = line - start_line + 1;
        }
    }
    printf("Copied lines %d from %s to %s\n",
           lines_copy, source_file, destination_file);

    fclose(source);
    fclose(destination);
}

int main() {
    char source_file[80];
    char destination_file[80];
    int start_line, end_line;

    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 start and end line\n\n");

    printf(">subcopy.o ");
    if (scanf("%79s", source_file) != 1) {
        return 1;
    }
    printf("destination file-> ");
    if (scanf("%79s", destination_file) != 1) {
        return 1;
    }
    printf("Start and end lines: ");
    if (scanf("%d %d", &start_line, &end_line) != 2) {
        return 1;
    }

    cp(source_file, destination_file, start_line, end_line);

    return 0;
}