【问题标题】:how to read specific lines of a text document and write them to another text | C如何读取文本文档的特定行并将它们写入另一个文本 | C
【发布时间】:2016-12-01 14:09:02
【问题描述】:

我创建了一个函数,该函数将源文件的名称、目标文件的名称以及将复制到目标文件的源文件行的开始行和结束行作为参数,如下例所示.我要做的就是输入要复制到其他文本文件的行,如下例所示:

我向您展示的代码只是“读取”一个文本文件的内容并“写入”另一个文本文件。我想“写”用户给出的特定行,而不是整个文本文件

用户输入
Source_file.txt //目标文件将从中读取的文件
destination_file.txt //程序写入的新文件
2 3 // 它将打印到目标文件的行数: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;
}

【问题讨论】:

  • 您能描述一下您遇到的问题吗?
  • 我正在尝试评估 Linux cp 命令。该程序接受 3 个输入:1)我们将读取的文件 2)我们将写入的文件(源文件中的内容)3)我们想要从源文件复制到目标文件的行
  • 您所显示的代码有什么问题?你有构建错误吗?您是否遇到运行时错误或崩溃?出乎意料的结果? 您的问题是什么?read about how to ask good questions
  • 好的。该程序运行良好,它从一个文件中读取并创建整个内容。我要做的就是接受用户的行,例如 3 5。这意味着它将把源文件中的第 3 行到第 5 行写入目标文件。
  • ` char ch; ... while( ( ch = fgetc(source) ) != EOF )` 不起作用。 fgetc() 返回 int,而不是 char,因为 EOF 不能表示为 char 而要从文本文件中读取行,请参阅 the getline() function.

标签: c getline


【解决方案1】:

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

使用 fgets 代替 fgetc 可以让您计算行数。


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

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

【讨论】:

  • 你能解释一下怎么做吗?
【解决方案2】:

这是一个非常简单的解决方案,假设您知道为简单起见,一行的最大长度为 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);
    }
}

因为 fgets 返回 NULL,所以当 EOF 被 reched 时,while 循环将结束。

附:这里和那里可能会有一些轻微的错误,因为我写得很快并且靠记忆进行,但总的来说它应该可以工作。

【讨论】:

  • 我建议 MAX_LINE_SIZE 太短(使用 4096 或类似的东西)。除此之外,您将输出加倍间距(因为fgets() 保留换行符,因此输出格式不需要添加第二个。不过,两者都是琐事。
  • @JonathanLeffler 哦,是的,我不记得 fgets 保留换行符,固定 :) 至于 100,我只是选择了一个随机数作为占位符,但我同意它很小
  • 我需要插入这些行作为输入。还有一个参数lines_copy将用于此目的
  • @Eternal 要从文件中读取而不是从标准输入中读取,您只需将变量的名称放在 fgets 中。在您的情况下,它应该是fgets(line,MAX_LINE_SIZE,source)。如果那不是你要问的,我真的不明白你的问题对不起。另外,lines_copy 用于什么目的?
  • lines_copy 是我试图解决问题的方法。我的问题在我的黄色背景帖子中进行了解释。我想从文本文件 (a) 中复制特定的行,并使用特定的行制作另一个文本文件(a 的副本),例如第 2-3 行,如黄色背景中的示例
【解决方案3】:

你的程序有一些问题:

  • 不要使用gets(),可能会导致缓冲区溢出。

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多