Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wczytywanie stringow z pliku txt

Ostatnio zmodyfikowano 2016-11-28 18:44
Autor Wiadomość
Signore_Ercole
Temat założony przez niniejszego użytkownika
Wczytywanie stringow z pliku txt
» 2016-11-27 22:22:09
Witam. Borykam się z pewnym problemem w moim programie. Program to słownik angielsko-polski, wczytuje on plik txt, i zapisuje dane w tablicy stringów. Przy pobieraniu nowych slow zapisuje je, ale tylko ostanie słowa czyli kiedy dodaje wiecej niz jedno słowo z angielskim bądź polskim tłumaczeniem zapisuje on tylko jedno. Drugi problem to jak powrócić do początkowego menu, aby od nowa liczył ilość linii w pliku txt. Program starałem się pisać obiektowo, wiem, że to bardziej profesjonalnie powinno wyglądać, ale taki mój poziom narazie. Prosze o pomoc.
Podrzucam kod w 3 plikach

plik head.h
C/C++
#include <iostream>
using namespace std;

class Words
{
public:
    string english;
    string polish;
    int number;
    void read();
    void add_English_Polish( int );
    void add_Polish_English( int );
    void show( int );
};


plik functions.cpp

C/C++
#include <iostream>
#include "head.h"
#include <fstream> //file
#include <cstdlib> //exit()
using namespace std;

void Words::read()
{
    fstream file; //zmienna plikowa
    file.open( "Words.txt", ios::in );
    if( file.good() == false )
    {
        cout << "Opening file failed!";
        exit( 0 );
    }
    else
    {
        cout << "The file was successfully opened." << endl;
    }
}

void Words::show( int nr )
{
    cout << nr << ". " << english << " - " << polish << endl;
}

void Words::add_English_Polish( int nr )
{
   
    cout << nr << ". " << "Put a word: English then Polish" << endl;
    cin >> english >> polish;
}

void Words::add_Polish_English( int nr )
{
    cout << nr << ". " << "Put a word: Polish then English" << endl;
    cin >> polish >> english;
}

plik main.cpp

C/C++
#include <iostream>
#include "head.h"
#include <fstream> //file, zapis do pliku
#include <cstdlib> //exit()
using namespace std;
Words * w;
int line_number, n;
string const Plik( "Words.txt" );
//int *wsk[number];
int main()
{
    char space = ' ';
    //  algorytm obliczajacy ilosc slowek w pliku txt
    line_number = 0;
    string line;
    fstream file;
    file.open( "Words.txt", ios::in );
    while( getline( file, line ) )
         ++line_number;
   
    file.close();
   
    //Przyoisuje slowa z txt do tablicy
    w = new Words[ 200 ];
    file.open( "Words.txt" );
    for( int i = 0; i < line_number; i++ )
    {
        file >> w[ i ].english;
        file >> w[ i ].polish;
    }
   
    n = line_number;
    int c;
   
    //menu
    cout << endl << "Ilosc slowek: " << line_number << endl;
    cout << endl << "Choose one of the following options:" << endl << endl;
    cout << "1-Add English word" << endl;
    cout << "2-Add Polish word" << endl;
    cout << "3-Check base of words" << endl;
    cin >> c;
    switch( c )
    {
    case 1:
        {
            char ch;
            for( int i = line_number; i < 200; i++ )
            {
                w[ i ].add_English_Polish( i );
                cin >> ch;
                n = + line_number;
                n++;
                cout << "Add more? Y/N";
                if( ch == 'n' || ch == 'N' )
                     break;
                else if( ch == 'y' || ch == 'Y' )
                     continue;
                //sposob na zapiywanie do pliku
                ofstream file( Plik.c_str() );
                for( int i = line_number; i < n; i++ )
                {
                    file << w[ i ].english;
                    file << space;
                    file << w[ i ].polish;
                }
                file.close();
            }
            break;
            cout << endl;;
        case 2:
            {
                char ch;
                for( int i = line_number; i < 200; i++ )
                {
                    w[ i ].add_Polish_English( i );
                    cin >> ch;
                    n = + line_number;
                    n++;
                    cout << "Add more? Y/N";
                    if( ch == 'n' || ch == 'N' )
                         break;
                    else if( ch == 'y' || ch == 'Y' )
                         continue;
                   
                }
                ofstream file( Plik.c_str() );
                for( int i = line_number; i < n; i++ )
                {
                    file << w[ i ].polish;
                    file << space;
                    file << w[ i ].english;
                }
                file.close();
            }
            break;
        case 3:
            {
                for( int i = 0; i < n; i++ )
                {
                    w[ i ].show( i );
                }
            }
            break;
        }
    }
    return 0;
}















P-154194
karambaHZP
» 2016-11-27 22:58:59
Znasz klasy, metody i funkcje, a jedziesz na kodzie spagetti?
Podziel to sensownie na moduły. Nadaj swoim klasom i zmiennym sensowne nazwy
i sam zaczniesz widzieć problemy.
Zmienne globalne - samo zło. Tutaj niepotrzebne.
using namesapce std;
 w pliku nagłówkowym to zła praktyka.
Pchanie logiki do
switch
a powinno być karalne. Istnieją funkcje.

Są kontenery, które idealnie pasują do słownika.
np. std::multimap.

edit: jak możesz wstaw kilka linii pliku, z którego czytasz hasła do słownika.

edit2: proste użycie std::multimap.
C/C++
#include <iostream>
#include <fstream>
#include <string>
#include <map>


class Dictionary {
public:
    using mmapDictionary = std::multimap < std::string, std::string >;
private:
    mmapDictionary dictionary;
    void Load();
    const bool IsEntryExist( const std::string & entry, const std::string & translation ) const;
public:
    Dictionary();
    void AppEntry( const std::string & entry, const std::string & translation );
    const mmapDictionary & GetDictionary() const { return this->dictionary; } // metoda inline
    void Save() const;
    friend std::ostream & operator <<( std::ostream & out, const Dictionary & dictionary );
};

Dictionary::Dictionary()
{
    Load();
}

void Dictionary::Load()
{
    std::ifstream fin( "fileName.txt" );
    if( fin ) {
        while( true ) {
            typename mmapDictionary::key_type keyEng;
            typename mmapDictionary::mapped_type mappedPl;
            fin >> keyEng >> mappedPl;
            if( !fin.eof() ) {
                this->dictionary.insert( decltype( this->dictionary )::value_type( keyEng, mappedPl ) );
            }
            else {
                fin.clear();
                fin.close();
                break;
            }
        }
    }
    else {
        // niepowodzenie
    }
}

const bool Dictionary::IsEntryExist( const std::string & entry, const std::string & translation ) const
{
    auto range = this->dictionary.equal_range( entry );
    if( range.first != this->dictionary.cend() ) {
        for( auto i = range.first; i != range.second; ++i ) {
            if( i->second == translation ) {
                std::cout << "haslo istnieje\n";
                return true;
            }
        }
    }
    return false;
}

void Dictionary::Save() const
{
    std::ofstream fout( "fileName.txt", std::ios::trunc );
    if( fout ) {
        for( auto const & item: this->dictionary ) {
            fout << item.first.data() << ' ' << item.second.data() << '\n';
        }
    }
    else {
        // niepowodzenie
    }
}

void Dictionary::AppEntry( const std::string & entry, const std::string & translation )
{
    if( !IsEntryExist( entry, translation ) ) {
        this->dictionary.insert( decltype( this->dictionary )::value_type( entry, translation ) );
    }
}

// funkcje pomocnicze
std::ostream & operator <<( std::ostream & out, const Dictionary & dictionary )
{
    for( auto const & item: dictionary.dictionary ) {
        out << item.first << ' ' << item.second << '\n';
    }
    return out;
}

int main()
{
    Dictionary dict;
    dict.AppEntry( "good", "dobry" );
    dict.AppEntry( "different", "inny" );
    dict.AppEntry( "alone", "samotny" );
    dict.Save();
   
    Dictionary dict2;
    std::cout << dict2 << '\n';
}
P-154197
j23
» 2016-11-28 11:21:42
@karambaHZP, rozwiązanie z multimapą, które podałeś, jest OK. Problem w tym, że jest jednokierunkowe. Tutaj (dwóch) multimap użyłbym to tworzenia relacji między słowami, a same słowa trzymałbym w oddzielnych kontenerach. np. vector<> czy list<>.
P-154206
michal11
» 2016-11-28 11:42:21
Można też skorzystać z bimapy

ew.
Frazy, które należy wpisać w wyszukiwarkę google:
P-154207
Signore_Ercole
Temat założony przez niniejszego użytkownika
» 2016-11-28 12:12:21
@karambaHZP, ogolnie sposób rozwiązania podany przez Cb jest dla mnie niezrozumiały, bo to jeszcze nie mój poziom. Dopiero zacząłem się wdrażać w OOP i prawdopodobnie za wcześnie chciałem napisać jakiś program, gdzie widze ze nie znam podstaw. Dzięki za odpowiedzi, menu zrobię za pomocą funkcji, wieczorem postaram się podrzucić nowy kod.
Próbowałem skompilować kod w C::B i pokazało 29 error, a w VS 2015 zero błędów, (ostatecznie przerzucam się na VS)
Ogólnie dzięki za kod bo dla mnie jest mega ambitny na tą chwile i mam co analizować w najbliższym czasie, mam pare pytan.

Dlaczego nie można używać
using namespace std;
 w plikach header, oraz dlaczego praktycznie się tego nie stosuje tylko np:
void AppEntry( const std::string & entry, const std::string & translation )
 w takiej postaci?

P-154209
mateczek
» 2016-11-28 15:03:48

Próbowałem skompilować kod w C::B i pokazało 29 error, a w VS 2015 zero błędów, (ostatecznie przerzucam się na VS)
Pewnie z powodu braku włączenia c++11
https://youtu.be/SNLZEhWZ1og​?t=259
P-154215
karambaHZP
» 2016-11-28 15:18:56
Dlaczego nie można używać
using namespace std;
 w plikach header,
Ponieważ dodajesz przestrzeń nazw we wszystkich miejscach i tracisz kontrolę, gdzie i kiedy jest dodana.
Poza tym nie praktykuje się takiego rozwiązania.
Ograniczasz sobie w ten sposób zasób identyfikatorów zmiennych, funkcji itd.
Istnieje ryzyko zastosowania tej samej nazwy i zajdzie niejednoznaczność.

PS: dzięki @j23 i @michal11 za uwagi.
P-154216
Signore_Ercole
Temat założony przez niniejszego użytkownika
» 2016-11-28 18:44:30
@mateczek dzięki za link, teraz już wszystko się kompiluje.
P-154221
« 1 »
  Strona 1 z 1