Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Удаление предложений из текстового файла


Автор: ALI46 1.5.2008, 21:03
Дан текстовый файл, фразы в котором отделены друг от друга точками, а слова – пробелами и знаками препинания. Оставить в этом файле только те фразы, которые содержат не менее трех слов.
написать с использованием классов
в исходном текстовом файле написано
Код

Benchmark evaluation not clear. Mother wash. Sun is shinning. Black door. With carefully optimized.

на выходе должно получаться
Код

Benchmark evaluation not clear. Sun is shinning. With carefully optimized.

в моём же случае выводятся какие-то иероглифы

вот код который я написал без использования классов
Код

#include<string.h>
#include<stdio.h>
#include<conio.h>
#define N 109
int kf(int i,char ch[N])
{
    int l;
    for (l=i;l<N;l++)
    {    
        if (ch[l]=='.') break;
    }
    return l-1;
}
void main(void)
{
    int nf,kp,k,konf,i=0;
    FILE *f1 = fopen("old.txt", "r");
    FILE *f2 = fopen("new.txt", "a");   
    char ch[N];      
           fgets(ch,N,f1);      
    nf=0; 
    kp=0;
    while(kf(i,ch)<=N)
    {
        for (k=nf;k<=kf(i,ch);k++)
            if (ch[k]==' ') kp++;
        if (kp>1)
        {
            for (k=nf;k<=kf(i,ch);k++)
                fputc(ch[k],f2);
            fputc('.',f2);
            fputc(' ',f2);
                    i=kf(i,ch)+2;
                    nf=i;
        }
    }
    fclose(f1);
    fclose(f2);  
}


помогите пожалуйста, чтобы всё удалялось корректно

Автор: Carnifex 2.5.2008, 12:43
ALI46, почти во всех IDE есть отладчик, он тебе поможет.

Автор: Droll 2.5.2008, 19:50
Без использования классов:
Код

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

int main(void)
{
    int kp;
    char *k, *nf, *kf;

    FILE *f1, *f2;

    // Открываем файл old.txt на чтение
    if ((f1 = fopen("old.txt", "r")) == 0)
    {
        printf("Ошибка при открытии файла old.txt");
        return 1;
    }

    // Открываем файл new.txt на добавление
    if ((f2 = fopen("new.txt", "a")) == 0)
    {
        printf("Ошибка при открытии файла new.txt");
        return 1;
    }

    const int N = 109;
    char ch[N];

    // Читаем фразы
    nf = fgets(ch, N, f1);
    if (!nf)
    {
        printf("Ошибка чтения файла old.txt");
        return 1;
    }

    // Ищем конец очередной фразы
    while ((kf = strchr(nf, '.')) != NULL)
    {
        // Счетчик пробелов
        kp = 0;
        for (k = nf; k <= kf; k++)
            if (*k == ' ')  kp++;
        // Если пробелов больше одного, то слов больше двух
        if (kp > 1)
        {
            // Записываем в файл
            if (nf != ch) fputc(' ', f2);
            for (k = nf; k <= kf; k++)
                fputc(*k, f2);
        }
        nf = ++kf;
        while (*nf == ' ') nf++;
    }

    // Для последующих добавлений к файлу
    fputc(' ', f2);

    // Сохраняем результат и закрываем файлы
    fflush(f2);
    fclose(f2);
    fclose(f1);  

    return 0;
}



Написанная Вами функция kf(), ИМХО, лишняя - она делает почти тоже самое, что и функция strchr.

Автор: ALI46 2.5.2008, 20:04
Droll, Огромное человеческое СПАСИБО!!! smile 

Автор: ALI46 3.5.2008, 21:50
а как её сделать через потоки?

Автор: Droll 4.5.2008, 18:03
Да, в общем-то, похоже...
Вместо FILE использовать потоки (ifstream - для чтения файла, ofstream - для записи в файл).
Чтобы открыть файл на запись с добавлением в конец файла, использовать флаг ios::app.
Чтение производить с помощью метода get, запись символа - с помощью put(char ch).

Пример:
Код

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(void)
{
    int kp;
    char *k, *nf, *kf;

    // Открываем файл old.txt на чтение
    ifstream f1("old.txt");
    if (!f1)
    {
        cout << "Ошибка при открытии файла old.txt" << endl;
        return 1;
    }

    // Открываем файл new.txt на добавление
    ofstream f2("new.txt", ios::app);
    if (!f2)
    {
        cout << "Ошибка при открытии файла new.txt" << endl;
        // Закрываем файл old.txt
        f1.close();
        return 1;
    }

    const int N = 109;
    char ch[N];

    // Читаем фразы
    f1.get(ch, N);
    if (f1.fail())
    {
        cout << "Ошибка чтения файла old.txt" << endl;
        f1.close();
        f2.close();

        return 1;
    }

    // Закрываем файл old.txt
    f1.close();

    nf = ch;

    // Ищем конец очередной фразы
    while ((kf = strchr(nf, '.')) != NULL)
    {
        // Счетчик пробелов
        kp = 0;
        for (k = nf; k <= kf; k++)
            if (*k == ' ')  kp++;
        // Если пробелов больше одного, то слов больше двух
        if (kp > 1)
        {
            // Записываем в файл
            if (nf != ch) f2.put(' ');
            for (k = nf; k <= kf; k++)
                f2.put(*k);
        }
        nf = ++kf;
        while (*nf == ' ') nf++;
    }
    // Для последующих добавлений к файлу
    f2.put(' ');

    // Сохраняем результат и закрываем файл new.txt
    f2.flush();
    f2.close();

    return 0;
}


Автор: ALI46 4.5.2008, 18:48
Droll, большое СПАСИБО!

Автор: ALI46 5.5.2008, 11:54
блин такой облом((( препод прогу забраковал и сказал переделать так, чтобы она не только со строками работала, а с полноценным текстом, то есть всё правильно удаляла из подобных текстов:
Код

Kakoi to text. Eshe text. Text pobolshe etogo.
Sovsem drugoy text. Text malenkiy. Text takogo
tipa. Takoy
text. A tak je vot takoy text.
Text. I eto text.

и получалось вот так
Код

Kakoi to text. Text pobolshe etogo.
Sovsem drugoy text. Text takogo
tipa. A tak je vot takoy text.


как это сделать? smile 

Автор: Droll 5.5.2008, 19:07
Приблизительно вот так:
Код

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(void)
{
//    int kp;
//    char *k, *nf, *kf;
    // Открываем файл old.txt на чтение
    ifstream f1("old.txt");
    if (!f1)
    {
        cout << "Ошибка при открытии файла old.txt" << endl;
        return 1;
    }
    // Открываем файл new.txt на запись
    ofstream f2("new.txt");
//, ios::app);
    if (!f2)
    {
        cout << "Ошибка при открытии файла new.txt" << endl;
        // Закрываем файл old.txt
        f1.close();
        return 1;
    }

    // Максимальное количество символов в строке
    const int N = 256;
    // Строка
    char ch[N];
    // указатель на конец фразы
    char *kf = ch;
    *kf = 0;
    // Счетчик пробелов
    int kp = 0;

    // Посимвольно считываем файл до конча
    while ((*kf = f1.get()) != EOF)
    {
        // Пробел или переход на другую строку
        if ((*kf == ' ') || (*kf == '\n'))
        {
            // Увеличиваем счетчик
            kp++;
            // Переходим к следующему символу в массиве
            kf++;
            *kf = ' ';
            // Ищем следующий символ, не равный пробелу
            while ((*kf = f1.get()) == ' ');
            if (*kf == '\n')
            {
                *(kf-1) = '\n';
                while ((*kf == ' ') || (*kf == '\n')) *kf = f1.get();
            }
        }
        // Пришли к точке
        if (*kf == '.')
        {
            if (kp > 1)
                // Если пробел стоит перед точкой
                if ((*(kf-1) == ' ') || (*(kf-1) == '\n'))
                {
                    // Уменьшаем счетчик
                    kp--;
                    // Заменяем пробел на точку
                    kf--;
                    *kf = '.';
                }
            kf++;
            // Признак окончания строки
            *kf = 0;
            // Если количество пробелов больше 1,
            // то пишем в файл
            if (kp > 1) f2 << ch << ' ';
            // Переходим в начало строки
            kf = ch;
            *kf = 0;
            // Сбрасываем счетчик
            kp = 0;
            *kf = ' ';
            // Ищем первый символ в фразе, не равный пробелу
            while ((*kf = f1.get()) == ' ');
            if (*kf == '\n')
            {
                kf++;
                *kf = ' ';
                while ((*kf == ' ') || (*kf == '\n')) *kf = f1.get();
            }
        }
        kf++;
    }

    f1.close();

    if (kp > 1)
    {
        *kf = 0;
        f2 << ch << '.';
    }

    f2.flush();
    f2.close();

    return 0;
}


Автор: ALI46 5.5.2008, 19:21
Droll, респект тебе и уважуха!!! smile  у меня прям слов нет...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)