如何在C中的不同行中将字符串写入文件 [英] How to write string to file in different lines in C

查看:79
本文介绍了如何在C中的不同行中将字符串写入文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,可以用一个文件替换一个文件中的一个单词,但是在新文件中,所有行都写成一行,而不是按要求写在不同的行和段落中.

I have program that replaces a word in a file with another one, but in the new file the lines are all written as one line, not in different lines and paragraphs as required.

我尝试在要从原始文件读取的每一行的末尾添加'\n',但是它不起作用.

I tried adding '\n' at the end of each line I am reading from the original file, but it is not working.

这是我的代码:

int main() {
    FILE *f1, *f2;
    char word[MAX], fname[MAX];
    char s[MAX], replace[MAX];
    char temp[] = "temp.txt", *p1, *p2;
    printf("Enter your input file name:");
    fgets(fname, MAX, stdin);
    fname[strlen(fname) - 1] = '\0';

    scanf("%s", word);

    scanf("%s", replace);

    f1 = fopen(fname, "r");
    if (!f1) {
        printf("Unable to open the input file!!\n");
        return 0;
    }
    f2 = fopen(temp, "w");
    if (!f2) {
        printf("Unable to open temporary file!!\n");
        return 0;
    }

    while (fscanf(f1,"%[^\n]%*c", &s) != EOF) {
        printf("%s",s); //I wanted to see what happens when I'm reading from the file. Previously I added at the end of string s the char '\n' but it didnt work

        if (strstr(s, word)) {
            p2 = s;
            while (p1 = strstr(p2, word)) {
                while (p2 != p1) {
                    fputc(*p2, f2);
                    p2++;
                }
                p1 = p1 + strlen(word);
                fprintf(f2, "%s", replace);
                p2 = p1;
            }
            while (*p2 != '\0') {
                fputc(*p2, f2);
                p2++;
            }
        } else {
            fputs(s, f2);
        }
    }

    fclose(f1);
    fclose(f2);

    remove(fname);

    rename(temp, fname);
    return 0;
}

推荐答案

出于多种原因,您应该使用fgets()而不是fscanf(f1,"%[^\n]%*c", &s)来读取输入文件:

You should use fgets() to read from the input file instead of fscanf(f1,"%[^\n]%*c", &s) for multiple reasons:

  • 您不给fscanf()最多要存储到s中的字符数:输入文件中任何足够长的行都会导致未定义的行为.
  • 您从f1中读取了该行,并明确跳过了换行符,这解释了为什么从未将换行符写入f2的原因.
  • fscanf()将在空行上失败,因为没有与\n相同的字符可读取到ss未修改,并且像上一行一样被处理(或第一行未定义的行为) ,并且循环在输入文件中的同一位置进行迭代,有效地永久性地阻塞了对f2的写入,但无济于事...
  • you do not give fscanf() to maximum number of characters to store into s: any sufficiently long line in the input file will cause undefined behavior.
  • you read the line from f1 and explicitly skip the newline, this explains why the newline never gets written to f2.
  • fscanf() will fail on an empty line because there are no characters different from \n to read into s, s is unmodified and gets handled like the previous line (or undefined behavior on the first line), and the loop iterates at the same spot in the input file, effectively stuck forever writing to f2 to no avail...

以下是经过纠正和简化的版本:

Here is a corrected and simplified version:

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

#define MAX  100

int main() {
    FILE *f1, *f2;
    char word[MAX], fname[MAX];
    char s[MAX], replace[MAX];
    char temp[] = "temp.txt";
    char *p1, *p2;

    printf("Enter your input file name: ");
    if (!fgets(fname, sizeof fname, stdin))
        return 1;
    fname[strcspn(fname, "\n")] = '\0';  /* strip the newline if present */

    printf("Enter the word to search: ");
    if (scanf("%99s", word) != 1)
        return 1;

    printf("Enter the replacement word: ");
    if (scanf("%99s", replace) != 1)
        return 1;

    f1 = fopen(fname, "r");
    if (!f1) {
        fprintf(stderr, "Unable to open the input file %s\n", fname);
        return 1;
    }
    f2 = fopen(temp, "w");
    if (!f2) {
        fprintf(stderr, "Unable to open temporary file %s\n", temp);
        return 1;
    }

    while (fgets(s, sizeof s, f1)) {
        p1 = s;
        while ((p2 = strstr(p1, word)) != NULL) {
            while (p1 < p2) {
                fputc(*p1++, f2);
            }
            fputs(replace, f2);
            p1 += strlen(word);
        }
        fputs(p1, f2);
    }

    fclose(f1);
    fclose(f2);

    remove(fname);
    rename(temp, fname);
    return 0;
}

但是请注意,如果输入文件中的行很长且匹配项跨越了fgets()读取的多个块,则程序将丢失这些匹配项.

Note however that if the input file has very long lines with matches spanning multiple chunks read by fgets(), these matches will be missed by the program.

这里是避免此问题的另一种方法:

Here is a different approach to avoid this problem:

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

#define MAX  100

int main() {
    FILE *f1, *f2;
    char fname[MAX], word[MAX], replace[MAX];
    char temp[] = "temp.txt";
    char *p1 *p2;
    int c;

    printf("Enter your input file name: ");
    if (!fgets(fname, sizeof fname, stdin))
        return 1;
    fname[strcspn(fname, "\n")] = '\0';  /* strip the newline if present */

    printf("Enter the word to search: ");
    if (scanf("%99s", word) != 1)
        return 1;

    printf("Enter the replacement word: ");
    if (scanf("%99s", replace) != 1)
        return 1;

    f1 = fopen(fname, "r");
    if (!f1) {
        fprintf(stderr, "Unable to open the input file %s\n", fname);
        return 1;
    }
    f2 = fopen(temp, "w");
    if (!f2) {
        fprintf(stderr, "Unable to open temporary file %s\n", temp);
        return 1;
    }

    p2 = word;
    while ((c = getc(f1)) != EOF) {
        if (c != '\0' && *p2 == (char)c) {
            p2++;
            if (*p2 == '\0') {
                fputs(replace, f2);
                p2 = word;
            }
        } else {
            for (p1 = word; p1 < p2;) {
                putc(*p1++, f2);
                /* find potential match for special cases: find aab in aaab */
                if (!memcmp(word, p1, p2 - p1) && word[p2 - p1] == (char)c)
                    p2 = word + (p2 - p1) + 1;
                    p1 = word;
                    break;
                }
            }
            if (p1 == p2) {
                putc(c, f2);
            }
        }
    }
    /* flush potential partial match at end of file */
    for (p1 = word; p1 < p2; p1++) {
        putc(*p1, f2);
    }
    fclose(f1);
    fclose(f2);

    remove(fname);
    rename(temp, fname);
    return 0;
}

这篇关于如何在C中的不同行中将字符串写入文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆