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


Автор: Slammer 9.3.2009, 00:35
Добрый вечер!

Задание: Написать программу, которая работает таким способом -
Пользователь вводит текст (строка до 40 символов. может состоять из несколько слов), который мы ищем в уже существуешем фаиле. Если ведёный текст совподает с тем что имеется в фаиле, тогда выводим его в другой фаил, указав номер строки, где он был найден.
Обробатывать сущесвуюший фаил можно только по симболам и в текстовом режиме.

Мне +- идея понятна как необходимо делать, но проблема в самой реализации, учитывая то, что знания почти нулевые в программном деле. Пожалуйста на мануал не отсылать, очень сложно в нём разобратся без помоши.

Часть кода, которую я пытался написать сам, с уймой ошибок :(
Спасибо за помощь! В приложении просто глупый пример существуешего фаила.
Код

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
    char c, z;
    char n[40];
    cin.getline(n, 40);
    int length, count=1;;
    
    int l, line;
    
    fstream fin("in.txt", ios::in);
    fstream fout("out.txt", ios::out);
    
    z = *n;
    l = *n;

    length=n.gcount(); //get user input size

    n.get(z);//first symbol of user input
    cout<<z;
    fin.get(c);//first symbol of file
    
    while(!fin.eof()){
        if(z == c){ //if found at least one character
             for(int i=1;i<=length;i++){
                     char get(z); // next symbol of user input
                     fin.get(c); // next symbol of text file
                     if(z==c) count++;
             }
             if(count==length){
                              fout<<"Line: "<<line<<"; "<<n; //put in output file line number + searching text
             }
        }
        else{ fin.get(c); count=2;}
    };
    
    char clear(z);
    fin.close();
    fout.close();
    
    system("pause");
    return 0;
}

Автор: Avaj 9.3.2009, 09:10
Ну кое-как потестил - вроде нормально всё:

Код

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

using namespace std;

int main(){
    ifstream fin("txt_file.txt");
    if(!fin){
        cout << "Error : input file not found" << endl;
        return 1;
    }
    string str;
    getline(cin, str);//считывание введённой строки
    if(str.length() == 0 || str.length() > 40) cout << "Error : illegal lenght of input string" << endl;
    else{
        int len = str.length(), i, line = 1;
        char ch;
        ofstream fout("output_file.txt");
        while(fin.get(ch)){//Поиск с начала файла
            i = 0;
            if(ch == str[0]){//если в файле найден первый символ искомой строки,
                i = 1;       //то начиная с него последовательно ищутся остальные символы
                while(fin.get(ch)){
                    if(i < len){
                        if(ch == str[i]) i++;
                        else{
                            if(ch == '\n') line++;
                            break;
                        }
                    }
                    else goto label;//Если строка найдена - переход по метке.
                }
            }
            else if(ch == '\n') line++;
        }
        label:;
        if(i == len) fout << line << endl << str;//строка найдена, печать в файл.
        else fout << "Input string not found.";
        fout.close();
    }
    fin.close();
    return 0;
}


Юзал MinGW / G++.

Автор: zim22 9.3.2009, 14:04
вот мой вариант.

Код
#include <fstream>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
    ifstream in("in.txt");
    ofstream out("out.txt");    
    string line;    
    
    do
    {
        getline(cin, line);    
    }
    while (line.size() > 40);
    
    size_t line_number = 1;            
    size_t cnt = 0;

    char c;
    while (!in.get(c).eof())
    {
        if (c == '\n')
            ++line_number;
        
        (c == line[cnt]) ? ++cnt : cnt = 0;            

        if (cnt == line.size())
            out << line << "(" << line_number << ")" << endl;
    }        
    return 0;
}

Автор: Avaj 9.3.2009, 15:38
zim22, И действительно - получилось короче. smile 

Но если получше потестить, то...

например если входной файл такой:

Цитата

aa


а искать в нём :

Цитата

a
, то неверно. smile 

Автор: zim22 9.3.2009, 15:54
Avaj, спасибо за тестирование smile
я забыл обнулить cnt, после того как, вхождение подстроки найдено.
надо так:
Код
out << line << "(" << line_number << ")" << endl, cnt = 0;

Автор: Slammer 10.3.2009, 23:26
Спасибо за быстрые ответы и помощь!

Автор: Anikmar 11.3.2009, 00:03
Цитата(Slammer @  10.3.2009,  23:26 Найти цитируемый пост)
Спасибо за быстрые ответы и помощь!

+1

Добавлено через 13 минут и 1 секунду
Slammer, То-ли я что-то не то нажал, то-ли сафари глючит (а он действительно иногда глючит). В общем я вам поставил + за помощь вам же, хотя адресовывал его zim22. Может и я не туда жамкнул. Так что извините.

Автор: bsa 11.3.2009, 09:33

M
bsa
Slammer, если ответ на вопрос получен, то пометь тему решенной

Автор: Slammer 15.3.2009, 22:48
Всем опять добрый вечер. Оказывается, не правильно понял условия задачи.

Выводить надо было все те строчки + номер строки, где был найден вводимый поисковой текст.
К примеру, из фаила txt_file.txt надо выводить 2, 3, 5, 6, 7 строки, если ищем 'to';


txt_file.txt
_______________________
That's bad news for the content industries, which have fired off letter 
after menacing letter to the site, only to see their threats posted on The Pirate Bay, 
together a with mocking replies. 
Viborg said that no one has successfully indicted The Pirate 
Bay or sued its operators in Swedish courts. 
Attorneys for DreamWorks and Warner Bros., two companies among those that have 
issued take-down demands to the site, did not return calls for comment.
_______________________

Помогите найти ошибку в моих карякулях:
Код

#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(){
    ifstream fin("txt_file.txt");
    ofstream fout("output_file.txt");
    if(!fin){
        cout << "Error: file not found" << endl;
        return 1;
    }
    char ch;
    int flag = 0, i = 0, j = 0, line = 0;
    string str;
    cout << "Input searching text: ";
    getline(cin, str);
    int len = str.length();
    
    label:;
    
    if(len == 0 || len > 40) cout << "Error: incorect input length" << endl;
    else{
        char *arr = new char;
        while(fin.get(ch)){
            if(ch != '\n' && flag == 0){
                arr[j] = ch;
                j++;
            }
            if(ch == '\n' && flag == 0){
                  line++;
            }
            else{ goto label2;}
        }
        if(ch == str[0] && flag == 0){
            i = 1;
            while(fin.get(ch)){
                if(ch != '\n'){
                    j++;
                    arr[j] = ch;
                }
                if(i < len){
                    if(ch == str[i]) i++;
                    else{
                        if(ch == '\n') line++;
                        break;
                    }
                }
                else{ flag = 1; goto label; }
            }
        }
                
        label2:;
        
        if(i == len && flag == 1){
             fout << line << endl; 
             for(int z = 0; z <= j; z++){
                     fout << arr[z];
             }
             j = 0;
             i = 0;
             fout << endl;
        }
        else if(!flag && fin.eof()){ 
             cout << "Nothing found" << endl;
             fout << "";
        }
        delete arr;
        while(fin.get(ch)){
           goto label2;
           flag, i, j = 0;
        }
        fout.close();
   }
    fin.close();
    system("pause");
    return 0;
}

Спасибо!

Автор: zim22 15.3.2009, 23:25
Цитата(Slammer @  9.3.2009,  00:35 Найти цитируемый пост)
Обробатывать сущесвуюший фаил можно только по симболам и в текстовом режиме.

если под обработкой будет подразумеваться считывание строк в вектор - это нормально?
или тебе и сравнение необходимо посимвольно делать?

Автор: Slammer 16.3.2009, 11:05
Сравнение необходимо посимвольно делать..

Тем самым, в начале цикла - просто все символы по очерёдности вкладываем в динамический массив. Параллельно проверяем нету ли там искаемой строки. Когда переходим к следуюшей строки - проверяем печатать ли текущею строку или нет. Удаляем массив. Повтор цикла..

В коде совершил ошибку, но не пойму где. smile 

Автор: zim22 16.3.2009, 11:12
Slammer, если мы ищем слово "ews". без буквы n в начале.
прога должна найти что-нибудь?

Автор: Dmi3ev 16.3.2009, 11:44
Цитата

прога должна найти что-нибудь? 

думаю, что да
вот два поиска: Кнута-Морриса-Пратта (быстрый) и простой (медленный)
Код

//
//Простой поиск
//
int my_simple_search(char *mystr, char *mytext)
{
    int mystr_l=strlen(mystr);
    int mytext_l=strlen(mytext);
    for (int i=0; i<=mystr_l-mytext_l; i++)
    {
        int j=0;

        while(j<mytext_l && (mytext[j]==mystr[i+j]))
        {
            j++;
        }
        if (j==mytext_l)
        {        
            return i;
        }
    }
    return (-1);
}
//
//Алгоритм Кнута-Морриса-Пратта
//
int  my_KMP_search  (char s[],   char q[])
    { 
    int  i, j, N, M; 
    N = strlen(s); 
    M = strlen(q); 
    int *d =new int[M];

    i=0; 
    j=-1;
    d[0]=-1;
    while(i<M-1)
        {
        while((j>=0) && (q[j]!=q[i]))
            j = d[j];
        i++;
        j++;
        if(q[i]==q[j])
            d[i]=d[j];
        else
            d[i]= j;
        }

    for(i=0,j=0;(i<=N-1)&&(j<=M-1); i++,j++)
        while((j>=0)&&(q[j]!=s[i]))
            j=d[j];
    delete[] d; 
    if (j==M)
        return (i-j);
    else 
        return (-1);
    }

Автор: Slammer 16.3.2009, 21:35
Цитата(zim22 @ 16.3.2009,  11:12)
Slammer, если мы ищем слово "ews". без буквы n в начале.
прога должна найти что-нибудь?

да. 

эмм. теперь думаю над теми двумя алгоритмами.

Автор: Dmi3ev 16.3.2009, 23:16
взял первый алгоритм, для примера:
Код

#include "stdafx.h"

#include <fstream>
#include <iostream>

using namespace std;
int my_simple_search(char *mystr, char *mytext)
{
    int mystr_l=strlen(mystr);
    int mytext_l=strlen(mytext);
    for (int i=0; i<=mystr_l-mytext_l; i++)
    {
        int j=0;
        while(j<mytext_l && (mytext[j]==mystr[i+j]))
            j++;
        if (j==mytext_l)
            return i;
    }
    return (-1);
}

int _tmain(int argc, _TCHAR* argv[])
{
    char buf[256];
    char text[40];

    cout<<"Enter your text: "<<endl;
    cin>>text;
    int counter=0;
    ofstream fo;
    ifstream fi;

    fi.open("D:\\1.txt");
    fo.open("D:\\2.txt");
    fo<<"I want find all strings with this text: "<<text<<endl;
    while (!fi.eof())
    {
        fi.getline(buf, 256);
        counter++;
        int pos=my_simple_search(buf, text);
        if (pos>=0)
            fo<<"Line: "<<counter<<" First position of text: "<<pos+1<<" String: "<<buf<<endl;
    }
    fo.close();
    fi.close();
    cout<<"I've done it!"<<endl;
    system("pause");
    return 0;
}

выходной файл имеет вид (номер строки, номер позиции первого символа текста (кот. мы искали), сама строка):
I want find all strings with this text: text
Line: 1 First position of text: 4 String: My text
Line: 2 First position of text: 14 String: lalalalalaal text
Line: 3 First position of text: 1 String: text
Line: 6 First position of text: 1 String: text
Line: 8 First position of text: 1 String: text
Line: 11 First position of text: 24 String: dsfadsfadsfasdfasdfasdftext

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