【问题标题】:How to read from file and write another in c如何从文件中读取并在c中写入另一个
【发布时间】:2020-05-17 13:54:35
【问题描述】:

我有一个这样的输入文件:

这是第 1 行。 这是第 2 行。 这第 3 行。

我需要输出类似的文件

OddLines.txt:

这是第 1 行。 这第 3 行。

EvenLines.txt:

这是第 2 行。

这是我的代码。并没有按我的意愿工作。

    char buf[256];
    int ch;
    int lines;
    lines = 1;

    FILE *myFile = fopen(argv[1], "r");

    if (myFile == NULL) {
        printf("Open error \n");
        exit(-1);
    }

    FILE *outFile = fopen("oddlines.txt", "w");
    FILE *outFile1 = fopen("evenlines.txt", "w");

    while (fgets(buf, sizeof(buf), myFile) != NULL) {
        if (ch == '\n')
            lines++;
        else
        if ((lines % 2) == 0)
            fputs(buf, outFile1);
        else
            fputs(buf, outFile);
    }
    fclose(myFile);
    fclose(outFile);
    fclose(outFile1);
}

【问题讨论】:

  • 欢迎来到 Stack Overflow。请阅读the help pages,接受SO tour,阅读How to Ask,以及this question checklist。最后,如果你问的是与一种编程语言相关的问题,那么请不要添加不相关的语言标签。
  • 提示:linesch的初始值是多少? ch 将如何获得价值?我还建议您在循环内执行一些rubber duck debugging 的代码。这真的有意义吗?
  • 您希望将这些行连接成输出文件中的单行还是在奇偶文件中显示为单独的行?

标签: c filestream fgets fputs


【解决方案1】:

不清楚您是否希望输出文件包含输入文件中的行,或者这些行是否必须连接起来,去掉换行符。

您的代码不起作用,因为测试 if (ch == '\n') 具有未定义的行为,因为 ch 未初始化。因此,行计数器未正确更新,所有行都进入其中一个文件。

计算行数实际上并不像计算循环的迭代次数那么简单,因为输入文件中的某些行可能比fgets() 使用的数组长度长。您应该在写入后通过测试刚刚写入的行是否实际上包含换行符来更新行计数器。

这是修改后的版本:

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

int main(int argc, char *argv[]) {
    char buf[256];
    int lines = 1;
    FILE *myFile, *outFile, *outFile1;

    if (argc < 2) {
        printf("Missing argument\n");
        return 1;
    }
    if ((myFile = fopen(argv[1], "r")) == NULL) {
        printf("Open error for %s\n", argv[1]);
        return 1;
    }
    if ((outFile = fopen("oddlines.txt", "w")) == NULL) {
        printf("Open error for %s\n", "oddlines.txt");
        return 1;
    }
    if ((outFile1 = fopen("evenlines.txt", "w")) == NULL) {
        printf("Open error for %s\n", "evenlines.txt");
        return 1;
    }

    while (fgets(buf, sizeof(buf), myFile) != NULL) {
        if (lines % 2 == 0)
            fputs(buf, outFile1);
        else
            fputs(buf, outFile);

        /* if a full line was read, increment the line number */
        if (strchr(buf, '\n')
            lines++;
    }
    fclose(myFile);
    fclose(outFile);
    fclose(outFile1);
    return 0;
}

这里有一个更简单的版本,不使用fgets()

#include <stdio.h>

int main(int argc, char *argv[]) {
    int c, out;
    FILE *myFile, *outFile[2];

    if (argc < 2) {
        printf("Missing argument\n");
        return 1;
    }
    if ((myFile = fopen(argv[1], "r")) == NULL) {
        printf("Open error for %s\n", argv[1]);
        return 1;
    }
    if ((outFile[0] = fopen("oddlines.txt", "w")) == NULL) {
        printf("Open error for %s\n", "oddlines.txt");
        return 1;
    }
    if ((outFile[1] = fopen("evenlines.txt", "w")) == NULL) {
        printf("Open error for %s\n", "evenlines.txt");
        return 1;
    }

    out = 0; /* current output file is "oddlines.txt" */
    while ((c = getc(myFile)) != EOF) {
        putc(c, outFile[out]);
        if (c == '\n')
            out = 1 - out;  /* change current output file */
    }
    fclose(myFile);
    fclose(outFile[0]);
    fclose(outFile[1]);
    return 0;
}

如果您想从第三个输出文件中去除元音,只需包含&lt;string.h&gt;,将该文件打开到FILE *noVowelFile 并在while 循环中添加一个测试:

    out = 0; /* current output file is "oddlines.txt" */
    while ((c = getc(myFile)) != EOF) {
        if (strchr("aeiouAEIOU", c) == NULL) {
            putc(c, noVowelFile);
        }
        putc(c, outFile[out]);
        if (c == '\n')
            out = 1 - out;  /* change current output file */
    }

【讨论】:

  • 我是初学者,所以我不太清楚 out ^= 1; 的表达方式;
  • @angunav:out ^= 1; 使用独占或在01 之间切换out。我将用更简单的表达式更新答案。
  • 这确实是其他版本的更简单版本。谢谢。
  • @angunav:谢谢。您介意回答这个问题吗:您希望将这些行连接成输出文件中的单行还是在奇数和偶数文件中显示为单独的行?
  • 这很好。我希望行在奇数和偶数文件中显示为单独的行。所以你介意回答这个问题:你想再帮我一次吗?如何再添加一个循环来检测和删除元音字母并写入另一个输出文件。我正在尝试,但我什至无法编写一行代码。
【解决方案2】:
if (ch == '\n')

这段代码没有意义。你想找到输入字符吗?如果是,你可以使用strcspn函数:

int pos = strcspn ( buf, "\n" );

lines 应该由 0 而不是 1 初始化:

    int lines = 0;
    while(fgets(buf, sizeof(buf),myFile))
    {
        lines++;
        int pos = strcspn ( buf, "\n" ); // find the enter character
        buf[pos] = ' '; // add space at the end of string
        buf[pos+1] = '\0';
        if ((lines%2)==0) // if even
            fputs (buf,outFile1); 
        else               // if odd
            fputs (buf,outFile);
    }

你应该检查fopen函数:

FILE *myFile = fopen(argv[1], "r");
if(!myFile) {return -1;}

FILE *outFile = fopen("oddlines.txt", "w");
if(!outFile) {return -1;}
FILE *outFile1 = fopen("evenlines.txt", "w");
if(!outFile1) {return -1;}

以及命令行的条件:

if(argc < 2 ) {
    printf("usage: %s <input_filename>", argv[0]);
    return-1;
}

完整代码:

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

int main(int argc, char const *argv[]) {

    char buf[256];
    int lines = 0;

    if(argc < 2 ) {
        printf("usage: %s <input_filename>", argv[0]);
        return-1;
    }

    FILE *myFile = fopen(argv[1], "r");
    if(!myFile) {return -1;}
    FILE *outFile = fopen("oddlines.txt", "w");
    if(!outFile) {return -1;}
    FILE *outFile1 = fopen("evenlines.txt", "w");
    if(!outFile1) {return -1;}

    while(fgets(buf, sizeof(buf),myFile)!=NULL)
    {
        lines++;
        int pos = strcspn ( buf, "\n" );
        buf[pos] = ' ';
        buf[pos+1] = '\0';
        if ((lines%2)==0)
            fputs (buf,outFile1);
        else
            fputs (buf,outFile);
    }

    fclose(myFile);
    fclose(outFile);
    fclose(outFile1);
}

输入文件:

This is 1nd Line.
This is 2nd Line.
This is 3rd Line.
This is 4th Line.
This is 5th Line.
This is 6th Line.

输出文件:

$cat evenlines.txt

This is 2nd Line. This is 4th Line. This is 6th Line. 

$cat oddlines.txt

This is 1nd Line. This is 3rd Line. This is 5th Line. 

【讨论】:

  • 不使用strcspn函数有没有办法做到这一点?
  • 在这种情况下你可以使用int pos = strlen(buf)-1; 或者你可以使用循环查找输入字符
  • buf[pos] = ' '; 可能会在行太长或文件不包含换行符时覆盖空终止符,从而在使用 fputs() 写入不再空终止的 buf 时导致未定义的行为.
  • @chqrlie 我添加了用于添加\0 字符的代码。感谢您的评论
  • @Hitokiri:恐怕您的修复不正确:如果行长于 255 个字节,pos 将等于 255buf[pos+1] = '\0'; 将超出 @ 的末尾987654342@。此外,在这种情况下增加 lines 以及插入额外的空格是不正确的。
【解决方案3】:
if (ch == '\n')

问题出在这一行。

#include <stdio.h>
#include<string.h>
void main() 
{
    int line=1;
    char buf[256];

    FILE *fp, *fp_Odd, *fp_Even;
    fp=fopen("USERS.TXT", "r");

    fp_Odd=fopen("ODD.TXT", "a");
    fp_Even=fopen("EVEN.TXT", "a");

    if(fp == NULL)
    {
        printf("Open error \n");
        exit(-1);
    }

    while(fgets(buf, sizeof(buf), fp)!=NULL)
    {
        if(strcmp(buf, "\n")==0)
        line++;

        else if(line%2 != 0)
            fprintf(fp_Odd, "%s", buf);
        else
            fprintf(fp_Even, "%s", buf);

        line++;
    }
    fclose(fp);
}

您可以检查此代码。我已经进行了必要的更改。希望你能理解。

【讨论】:

  • 您的代码似乎不正确:空行将导致line 增加两次。为什么要更改 OP 程序的文件名和命令行参数处理?
  • 否,如果有空行它不会增加两次。你可以使用任何你想要的文件名和命令行参数。我用过这些。
猜你喜欢
  • 2017-05-03
  • 2018-10-30
  • 1970-01-01
  • 2015-12-29
  • 2021-01-23
  • 1970-01-01
  • 2017-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多