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

Odczyt z danych z pliku - nietypowy układ

Ostatnio zmodyfikowano 2016-06-08 18:12
Autor Wiadomość
Silentraz
Temat założony przez niniejszego użytkownika
Odczyt z danych z pliku - nietypowy układ
» 2016-06-06 21:48:01
Planuję rozwinąć program, który zamiast wpisywania cinem, będzie czytał dane z pliku. Utrudnieniem jest jednak to, aby można było go edytować w notatniku.
Wielogodzinne przeszukiwanie internetów i notatki z zajęć nie są wystarczające, ewentualnie nie mogę ich zrozumieć. Format nieco się różni od tego co miałem okazję spotkać. Cinem i coutem to umiem cały problem rozwiązać, ale odczyt z pliku - jedynie pobierać liczby jedna obok drugiej

W pierwszych wersjach programu oczywiście było
cin>>NICK;
cin>>WWW;
cin>>YYY;
itd...

WWW etc - nazwy które nie będą zmieniane
liczby - będą zmieniane przez użytkownika. Sąsiedztwo z nazwą pozwoli określić co jest zmieniane.
dodatkowo - NICK czytany z pliku

//układ 1:{
NICK Silent

WWW 100
XXX 150
YYY 200
ZZZ 250

AAA 200
BBB 300
CCC 400

PPP 200
RRR 320
QQQ 440
}
//układ 2:{
NICK
Silent

WWW XXX YYY ZZZ
100 150 200 250

AAA BBB CCC
200 300 400

PPP RRR QQQ
200 320 440
}
//układ 3{
NICK Silent
WWW 100 XXX 150 YYY 200 ZZZ 250
AAA 200 BBB 300 CCC 400
PPP 200 RRR 320 QQQ 440
}

Potrzebuję porady lub jakiegoś kodu który pozwoli odczytywać z powyższych lub podobnych układów.
Założeniem jest to, by użytkownik z zielonym pojęciem o programowaniu mógł swobodnie przerabiać liczby, a także by nie trzeba było ich każdorazowo wprowadzać (program obejmuje ponad 20 wartości).


Dla ciekawych do czego mi to potrzebne - tu wersja programu (1.02/1.03 podczas założenia tematu):
https://drive.google.com/drive​/folders​/0BywB7a8c6EM8azJpRzhvdWVROEU
P-148935
carlosmay
» 2016-06-06 22:01:00
Z pliku też można odczytywać operatorem
>>
.
Dane są w miarę poukładane.

Można wczytać po kolei do zmiennej std::string i sprawdzać czy pierwszy znak jest cyfrą,
to da odpowiedź czy konwertować na zmienną liczbową czy zostawić jako napis.

PS:
cin<<NICK;
 - do pobierania danych do zmiennej służy operator
>>
.
PS2: Przy pobieraniu z pliku operatorem
>>
 układ pierwszy i trzeci obsłużysz identycznie.
Wczytywanie z pliku operatorem >>
P-148937
Silentraz
Temat założony przez niniejszego użytkownika
» 2016-06-06 22:12:32
Który układ byłby najkorzystniejszy?

"Można wczytać po kolei do zmiennej std::string i sprawdzać czy pierwszy znak jest cyfrą,"

Jakaś dodatkowa podpowiedź, przykładowa linijka? Jestem jeszcze noobem w programieniu i dla mnie to kolejne godziny zastanawiania.
P-148938
carlosmay
» 2016-06-06 22:27:11
Który układ byłby najkorzystniejszy?
Jeśli jest wybór to pierwszy lub trzeci.

C/C++
std::ifstream file( fileName );
std::string str;
int value;
while( file >> str >> value ) // pobierz parami aż do końca pliku
{
    // tutaj coś robisz z pobraną parą 'napis' i 'wartość'
}

Nie wiem jak dalej te dane będą przetwarzane, ale idealnie pasują do std::map ew std::multimap: np.
C/C++
std::multimap < std::string, int > lines;
//...
while( file >> str >> value ) // str = "aka"
{
    lines[ str ] = value;
}

// odczyt z tablicy asocjacyjnej
std::cout << lines[ "aka" ];
// można też tradycyjnie iterować po kontenerze
for( auto const & item: lines )
{
    std::cout << item.first << ' ' << item.second << '\n'; // wypisz napis i wartość z mapy
}
P-148939
Silentraz
Temat założony przez niniejszego użytkownika
» 2016-06-06 22:59:22
Pętla tu chyba odpadnie.
Uznajmy że z lewej plik notatnika, a z prawej to co chcę uzyskać.
{
Nick Silent //cin>>pla1

Poziom 50 //cin>>lvl1
Obrażenia_minimalne 60 //cin>>brmin1
Obrażenia_maksymalne 150 //cin>>brmax2

Siła 22 //cin>>sila1
Sprawność 44 //cin>>spraw1
Zręczność 88 //cin>>zrec1
Charyzma 124 //cin>>char1
}

Oczywiście chodzi o to, by najpierw sczytało nick a potem kolejno wartości o - jak widać - różnych nazwach.

Linijek będzie 20-30, więc tutaj ręczne pisanie zamiast pętli nie jest kretyńskim pomysłem.

Jak dane są przetwarzane - w linku z 1 posta. Sam program pod inny temat.
P-148940
Silentraz
Temat założony przez niniejszego użytkownika
» 2016-06-06 23:08:15
std::ifstream file( "stat.txt" );
std::string str;
int value;
file >> str >> pla1;
file >> str >> LVL1;
file >> str >> brmin1;
file >> str >> brmax2;
file >> str >> sila1;
file >> str >> spraw1;
etc...

Już mam... teraz będę kontynuować. Z opóźnieniem, ale porada zadziała.

Za jakiś czas podrzucę pełen kod, bo chyba plik powinien się zamykać, to się poszuka takich i podobnych błędów.
P-148941
carlosmay
» 2016-06-07 01:07:40
C/C++
#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <algorithm>

auto main()->int
{
    std::map < std::string, int > lines;
    std::string str;
    int value;
    std::ifstream file( "test.txt" );
   
    if( file.is_open() ) {
        while( file >> str >> value )
        {
            lines[ str ] = value;
            // lub
            // lines.insert(std::make_pair(str, value));
        }
    }
    else
         std::cerr << "error file" << '\n';
   
    std::for_each( lines.cbegin(), lines.cend(),
    []( const std::pair < std::string, int >& item ) { std::cout << item.first << ' ' << item.second << '\n'; } );
    // algorytm std::for_each można zastąpić pętlą zakresową
    //      for(auto const& item: lines)
    //      {
    //          std::cout << item.first << ' ' << item.second << '\n';
    //      }
   
    std::cout << "Szukanie wg klucza: \n";
    std::string findKey;
    std::cin >> findKey; // -->> QQQ
    auto posKey = lines.find( findKey );
    if( posKey != lines.end() ) {
        std::cout << posKey->first << ' ' << posKey->second << '\n'; // QQQ 444
    }
}

console output: dla wariantu nr 1
AAA 200
BBB 300
CCC 400
PPP 200
QQQ 444
RRR 320
WWW 100
XXX 150
YYY 200
ZZZ 250
Aby kontynuować, naciśnij dowolny klawisz . . .
P-148944
Silentraz
Temat założony przez niniejszego użytkownika
» 2016-06-07 02:28:38
C/C++
std::ifstream file( "stat.txt" );
std::string str;
file >> str >> pla1;
file >> str >> LVL1;
file >> str >> brmin1;
file >> str >> brmax2;
file >> str >> sila1;
file >> str >> spraw1;
file >> str >> zrec1;
file >> str >> char1;
file >> str >> bPZ1;
file >> str >> bchow1;
file >> str >> bzakp1;
file >> str >> bcel1;
file >> str >> bunik1;
file >> str >> bdowo1;

std::ifstream file2( "stat2.txt" );
std::string sts;
file2 >> sts >> pla2;
(...) //to samo co u góry ale z 2.
file2 >> sts >> bdowo2;

Pełen kod programu znajduje się w pliku "Test1" //nie umiem spoilerować, a wrzucenie 250 linijek kodu mogłoby dać sporo do przewijania.
https://drive.google.com​/folderview​?id=0BywB7a8c6EM8OV9lTXBSb0Jwd​m8​&usp=drive_web

Plik notatnika ma postać:

{Nick Silent
Poziom 550
Obrażenia_minimalne 50
Obrażenia_maksymalne 500
Siła 66
Sprawność 66
Zręczność 63
Charyzma 64
Punkty_Życia 270
Chowanie 770
Zakładanie_Pułapek 300
Celność 77
Unik 73
Dowodzenie 76}

Niestety gdy wyczytałem niektóre wartości coutem, wyszły inne wartości. Sam program dawał podejrzanie dziwne wyniki (np. bardzo zdecydowana wygrana mimo identycznych statystyk).

W czwartek wrócę do kodzenia, dziś i jutro będę mniej intensywnie zaglądał.
P-148945
« 1 » 2
  Strona 1 z 2 Następna strona