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

Zadanie domowe rozdział 34.

Ostatnio zmodyfikowano 2016-12-18 13:10
Autor Wiadomość
NukeeMann
Temat założony przez niniejszego użytkownika
Zadanie domowe rozdział 34.
» 2016-12-18 12:34:59
Witam. W zadaniu domowy z owego rozdziału miałem za zadanie pominąć zliczanie liczb w danym wierszy, jeżeli program napotka znak a nie liczbę. Wykonałem to zadanie w dość moim zdaniem prymitywny sposób. Wie ktoś jak w inny 'lepszy' sposób to zrobić?
C/C++
#include<iostream>
#include<fstream>
#include<string>

using namespace std;

bool czyNapotkanoZnakNowegoWiersza( std::ifstream & plik )
{
    char cZnak;
    for(;; ) //nieskończona pętla
    {
        plik.clear();
        cZnak = plik.peek(); //sprawdzamy jaki kolejny znak zostanie zwrócony przez operację odczytu
        if( plik.fail() || plik.bad() )
             return false; //wystąpił błąd odczytu danych
       
        if( !isspace( cZnak ) )
             return false; //pobrany znak nie jest białym znakiem
       
        plik.get( cZnak ); //odczytujemy biały znak z pliku
        if( plik.fail() || plik.bad() )
             return false; //wystąpił błąd odczytu danych
       
        if( cZnak == '\n' ) {
            return true;
        }
       
    } //for
}
bool wczytajplik( string dokument ) {
   
    int suma = 0;
    ifstream plik;
    plik.open( "dokument.txt" );
    if( !plik.good() )
         return false;
   
    string wiersz;
    int liniawiersza = 1;
    int iLiczba[ 20 ];
    int n = 0;
    char blad;
    while( !plik.eof() ) {
        if( czyNapotkanoZnakNowegoWiersza( plik ) ) {
            int i = 0;
            if( blad != 'N' ) {
                do {
                    suma += iLiczba[ i ];
                    i++;
                } while( i < n );
               
                cout << suma << endl;
            }
            suma = 0;
            liniawiersza++;
            i = 0;
            do {
                iLiczba[ i ] = 0;
                i++;
            } while( i < n );
           
            n = 0;
            blad = '0';
        }
        /*while(znaczek!='\n'){
        plik>>iliczebka;
        if(plik.fail()){
        plik>>znaczek;
        if(znaczke!='\n')
        return false;
        }
        else
       
        }*/
        plik >> iLiczba[ n ];
        if( plik.fail() ) {
            plik.clear();
            char znak;
            plik >> znak;
            if( plik.fail() ) {
                cout << "Nie udalo sie wczytaj zawartosci wiersza." << endl;
                return false;
            }
            else
            {
                blad = 'N';
                cout << "Nie udalo sie wczytac wiersza " << liniawiersza << endl;
            }
        }
        else
             n++;
       
    }
    plik.close();
    return true;
}

int main() {
   
    string plik = "dokument.txt";
    if( !wczytajplik( plik ) )
         cout << "Nie udalo sie wczytac pliku.";
   
    return 0;
}
P-155125
Gibas11
» 2016-12-18 13:10:59
1. Wczytuj plik wierszami używając
std::getline( plik, linia );
. Cały plik możesz wczytać tak:
C/C++
std::string linia;
std::ifstream plik( "file.txt" );
while( std::getline( plik, linia ) ) {
    /* Robienie czegoś z linią */
}

2. Mając string linii sprawdź czy jest w nim znak inny niż spacja lub cyfra. Najlepiej wg mnie użyć std::count_if i zliczyć wystąpienia tych złych znaków, jeśli jest ich zero to wiersz jest prawidłowy.
C/C++
bool sprawdz( std::string str ) {
    return std::count_if( str.begin(), str.end(),
    []( const char & c ) {
        return c != ' ' &&( c > '9' || c < '0' );
    } ) == 0;
}
Użyte przeze mnie wyrażenie lamda możesz zastąpić zwykłą funkcją.

3. Zsumować liczby w wierszu możesz używając std::istringstream, coś jak std::ifstream, ale nie otwiera pliku tylko jakiś string – bardzo wygodne.
C/C++
int zlicz( std::string str ) {
    std::istringstream stream( str );
    int suma = 0;
   
    for( int i; stream >> i; )
         suma += i;
   
    return suma;
}

//edit:
O, teraz dokładnie przeczytałem to zadanie i zobaczyłem w wymogach wykorzystanie funkcji
czyNapotkanoZnakNowegoWiersza
 (?) – jakie polecenie takie rozwiązanie, możesz ją wstawić w jakimś losowym miejscu byleby nie przeszkadzała. ;-;
P-155127
« 1 »
  Strona 1 z 1