Проблемы при попытке пропустить \ n при чтении текстовых файлов - PullRequest
0 голосов
/ 06 ноября 2019

Я написал очень маленькую программу, которая поможет с форматированием текстовых файлов, но когда я попытался прочитать из входных файлов и пропустить нежелательный '\ n', я фактически пропустил следующий символ после '\ n'.

Символы, над которыми я работаю в файле примера, выглядят так:

abcde
abc

   ab
abcd

И мой код выглядит следующим образом:

while (!feof(fp1)) {
    ch = fgetc(fp1);
    if (ch != '\n') {
        printf("%c",ch);
    }
    else {
        ch = fgetc(fp1); // move to the next character
        if (ch == '\n') {
            printf("%c",ch);
        }
    }
}

Ожидаемый результат -

abcdeabc
  ababcd

Но я действительно получил

abcdebc
   abbcd

Я думаю, проблема в ch = fgetc(fp1); // move to the next character, но я просто не могу найти правильный способ реализации этой идеи.

1 Ответ

1 голос
/ 06 ноября 2019

Подумайте о потоке вашего кода (строки пронумерованы ниже):

 1 while (!feof(fp1)) {
 2     ch = fgetc(fp1);
 3     if (ch != '\n') {
 4         printf("%c",ch);
 5     }
 6     else {
 7         ch = fgetc(fp1); // move to the next character
 8         if (ch == '\n') {
 9             printf("%c",ch);
10         }
11     }
12 }

Когда вы получаете новую строку, за которой следует не новая строка, поток (начинающийся со строки else): 6, 7, 8, 10, 11, 12, 1, 2.

Именно выполнение последнего 2 в той последовательности, которое фактически отбрасывает не-символ новой строки, который вы прочитали в 7.


Если вашНамерение состоит в том, чтобы в основном отбрасывать отдельные символы новой строки и преобразовывать последовательности строк (двух или более) в один (a) , вы можете использовать что-то вроде следующего псевдокода:

set numNewlines to zero
while not end-file:
    get thisChar
    if numNewlines is one or thisChar is not newline:
        output thisChar
    if thisChar is newline:
        increment numNewlines
    else:
        set numNewlines to zero

Это читает символ в одном месте, уменьшая вероятность того, что вы случайно пропустите его из-за запутанного потока. Он просто использует новую строку history , чтобы решить, что будет напечатано (он выводит только новую строку во втором вхождении в последовательности новых строк).


Некоторые актуальные Код C, который демонстрирует это (b) , следует:

#include <stdio.h>
#include <stdbool.h>

int main(void) {
    // Open file.

    FILE *fp = fopen("testprog.in", "r");
    if (fp == NULL) {
        fprintf(stderr, "Cannot open input file\n");
        return 1;
    }

    // Process character by character.

    int numNewlines = 0;
    while (true) {
        // Get next character, stop if none left.

        int ch = fgetc(fp);
        if (ch == EOF) break;

        // Output only second newline in a sequence of newlines,
        // or any non-nwline.

        if (numNewlines  == 1 || ch != '\n') {
            putchar(ch);
        }

        // Manage sequence information.

        if (ch == '\n') {
            ++numNewlines;
        } else {
            numNewlines = 0;
        }
    }

    // Finish up cleanly.

    fclose(fp);
    return 0;
}

(a) Из вашего вопроса неясно, как вы хотите обрабатывать последовательноститри или более символов новой строки, поэтому мне пришлось сделать предположение.


(b) Конечно, вы не должны использовать , если вы намереныэто учиться:

  1. Вы узнаете больше, если попробуете себя и исправите какие-либо проблемы.
  2. Учебные заведения почти наверняка проверят представленный код на основе поиска в Интернете, и выЯ, вероятно, буду наказан за плагиат.

Я просто предоставляю его для полноты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...