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

[Poziom 4 Lekcja 34] Zadanie lekko tuningowane - Zawieszenie programu po wczytaniu mix'a liter ze znakami.

Ostatnio zmodyfikowano 2014-01-08 20:18
Autor Wiadomość
pekfos
» 2013-12-27 18:40:56
Nie mogę sobie z tym poradzić już. Zanim napisałem tutaj męczyłem się parę dni z tym.
To wcześniej mogłeś sobie z tym poradzić? Nie pisz, ile się z tym nie męczyłeś, bo to nie ma ani znaczenia, ani wpływu na to, co tu piszemy. Podane przez Ciebie 3 kody nie są równoznaczne. Pierwsze dwa przez tę resztę kodu, która może zmienić stan flag błędu (jak w tym przypadku), a drugi i trzeci sprawdzają różne rzeczy. Strumień rzutowany na bool to nie jest !eof(). Co do wywołań peek(), to co napisałem wcześniej dalej jest aktualne. Niczego tu nie zrobiłeś.
P-100348
DejaVu
» 2013-12-27 20:08:21
Przeanalizuj:
C/C++
while( !plik.eof() )
{
    if( czyNapotkanoZnakNowegoWiersza( plik ) )
    {
       
        cout << "Suma liczb w " << wiersz << " wierszu to: " << suma << " Liczba bledow to: " << suma_bledow << endl;
        suma_bledow = suma = 0;
        wiersz++;
    } else
    {
        plik.clear();
        if( plik >> liczba )
        {
            suma += liczba;
        } else
        {
            suma_bledow++;
            plik.clear();
            plik.get();
        } //else
    } //else
} //while
P-100366
Krump
Temat założony przez niniejszego użytkownika
» 2013-12-27 20:37:05
Wykombinowałem i ruszyło, ale są kolejne problemy.
Zmieniony While:
C/C++
while( !plik.eof() )
{
    char znak = plik.peek();
    if(( znak >= '0' ) &&( znak <= '9' ) )
    {
        plik >> liczba;
        suma += liczba;
    }
    else
    //if( plik.fail() )
    {
        //plik.clear();
        //liczba = 0;
        suma_bledow++;
        while( !czyNapotkanoZnakSpacji( plik ) )
        {
            if( !czyNapotkanoZnakNowegoWiersza( plik ) )
                 plik.get();
            else
                 break;
           
        }
        if( plik.fail() )
        {
            plik.clear();
            plik.sync();
        }
    }
    cout << liczba << " ";
    if( czyNapotkanoZnakNowegoWiersza( plik ) )
    {
        cout << "Suma liczb w " << wiersz << " wierszu to: " << suma << " Liczba bledow to: " << suma_bledow << endl;
        suma = 0;
        wiersz++;
        suma_bledow = 0;
    }
}
Otóż tak:
1. Program ruszył jak natrafi na mix'a czyli 1d3, ale nie robi tego co chce, bo powinien odrzucić cały wyraz a on sumuje 1 a d3 odrzuca.
2. Przy natrafieniu na dwa błędy, np w linijce a d, zawiesza sie na drugim błędzie.

PS. Nie odświeżywszy strony i nie zauważyłem twojego. Sprawdziłem i twoje działa idealnie. Zaraz to dogłębnie przeanalizuje. Nie zamykajcie tematu bo będę miał na pewno pytania.
P-100372
Krump
Temat założony przez niniejszego użytkownika
» 2013-12-27 22:04:51
Jednak nie działa poprawnie.

Tylko najpierw mam jedno pytanie, dlaczego dałeś plik.clear()przed drugim if'em?

A teraz czemu nie działa... Otóż jak mamy taki zestawik w pliku:
C/C++
1 a 2 55
1 d 2 3
2 3 132 87
2d3 2 4
a d
5

Otrzymujemy taki wynik:

Suma liczb w 1 wierszu to: 58   Liczba bledow to: 1
Suma liczb w 2 wierszu to: 6    Liczba bledow to: 1
Suma liczb w 3 wierszu to: 224  Liczba bledow to: 0
Suma liczb w 4 wierszu to: 11   Liczba bledow to: 1
Suma liczb w 5 wierszu to: 0    Liczba bledow to: 2
Pierwsze co się rzuca, to nie zabrał się za 6, ostatnią linię.
Myślałem, że to problem z warunkiem w while(), ale zastosowanie for, jak mówił DejaVu tez nic nie dało. Zamieniałem nawet while() na do..while(), aby sprawdzał warunek po zrobieniu operacji, ale tez nic.
Dwa to w 4 linijce mamy 2d3 2 4, czyli wedle tego co chcemy uzyskać powinna być suma 6 i jeden błąd, czyli to co pierwotnie występowało, że 2d3 traktuje jako osobne wyrazy.

Co do swojego kodu jak DejaVu podał swój to spostrzegłem mójbłąd myślowy.
P-100382
Krump
Temat założony przez niniejszego użytkownika
» 2013-12-29 00:52:39
Any sugestions?
P-100453
pekfos
» 2013-12-29 13:07:22
Jaki jest aktualny kod?
P-100472
Krump
Temat założony przez niniejszego użytkownika
» 2013-12-29 17:04:07
Ogólnie to mam 3 xD
Ale mój pierwszy był denny i z poprawkami DejaVu jest lepszy, czyli:
C/C++
#include <iostream> //1 a 2 55
#include <fstream> //1 d 2 3
#include <stdlib.h> //2 3 132 87
#include <string> //2d3 2 4
#include <conio.h> //a d
//5
using namespace std;

bool czyNapotkanoZnakNowegoWiersza( std::ifstream & plik )
{
    char cZnak;
    for(;; )
    {
        plik.clear();
        cZnak = plik.peek();
        if( plik.fail() || plik.bad() )
             return false;
       
        if( !isspace( cZnak ) )
             return false;
       
        plik.get( cZnak );
        if( plik.fail() || plik.bad() )
             return false;
       
        if( cZnak == '\n' )
             return true;
       
    }
}

bool czyNapotkanoZnakSpacji( std::ifstream & plik )
{
    char cZnak;
    for(;; )
    {
        plik.clear();
        cZnak = plik.peek();
        if( plik.fail() || plik.bad() )
             return false;
       
        if( !isspace( cZnak ) )
             return false;
       
        plik.get( cZnak );
        if( plik.fail() || plik.bad() )
             return false;
       
        if( cZnak == ' ' )
             return true;
       
    }
};

int main( int argc, char ** argv )
{
    ifstream plik;
    int suma = 0, wiersz = 1, liczba = 0, suma_bledow = 0;
    plik.open( "text.txt" );
    if( !plik.good() )
    {
        cout << "Nie udalo sie otworzyc pliku :/ ";
        getch();
        return false;
    }
    while( !plik.eof() )
    {
        if( czyNapotkanoZnakNowegoWiersza( plik ) )
        {
            cout << "Suma liczb w " << wiersz << " wierszu to: " << suma << " Liczba bledow to: " << suma_bledow << endl;
            suma_bledow = suma = 0;
            wiersz++;
        }
        else
        {
            plik.clear();
            if( plik >> liczba )
            {
                suma += liczba;
            }
            else
            {
                suma_bledow++;
                plik.clear();
                plik.get();
            } //else
        } //else
    } //while
    plik.close(); // tu był blad, a rczej tego w ogóle nie było!
    getch();
    return 0;
}

Ale dzisiaj rano od początku napisałem i mi prawie działa (jak mam 2d3 to uznaje jako błąd), tylko się krzaczy jak w paru sytuacjach (jak są same błędy w linijce to ją pomija, jak w ostatnim wyrazie jest błąd to pomija linijki).
C/C++
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <conio.h>

using namespace std;

int jakiznaknapotkano( 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 0; //wystąpił błąd odczytu danych
       
        if( !isspace( cZnak ) )
             return 1; //pobrany znak nie jest białym znakiem
       
        plik.get( cZnak ); //odczytujemy biały znak z pliku
        if( plik.fail() || plik.bad() )
             return 0; //wystąpił błąd odczytu danych
       
        if( cZnak == ' ' )
             return 2; //sprawdza czy kolejna jest spacja
       
        if( cZnak == '\n' )
             return 3; //sprawdza czy kolejny jest nowy wiersz
       
    }
}
int main( int argc, char ** argv )
{
    ifstream plik;
    int suma = 0, wiersz = 1, liczba = 0, suma_bledow = 0, a = 0;
   
    plik.open( "text.txt" ); // Otwieranie pliku
    if( !plik.good() ) // Sprawdzanie pliku
    {
        cout << "Nie udalo sie otworzyc pliku :/ ";
        getch();
    }
   
    while( !plik.eof() ) // Operacja na pliku, kzakonczenie pętli gdy plik się kończy
    {
        plik >> liczba; // Pobieranie liczby
        if( plik.fail() ) // Sprawdzanie czy nie ma błędów
             plik.clear(); // Czyszczenie flanki błędów
       
        switch( jakiznaknapotkano( plik ) ) // Switch do wykonania okreslonej akcji
        {
        case 1: // Gdy kolejny znak to nie znak biały
            {
               
                cout << "1" << endl;
                while( jakiznaknapotkano( plik ) == 1 && !plik.eof() )
                {
                    plik.get();
                }
                liczba = 0;
                suma_bledow++;
                break;
            }
        case 2: // Gdy kolejny znak to spacja
            {
                cout << "2" << endl;
                suma += liczba;
                break;
            }
        case 3: // Gdy kolejny znak to enter (\n)
            {
                cout << "3" << endl;
                suma += liczba;
                cout << "Suma w wierszu " << wiersz << " wynosi: " << suma << ". Przy liczbe bledow: " << suma_bledow << endl;
                suma = 0;
                wiersz++;
                suma_bledow = 0;
                a = 0;
                break;
            }
        }
       
        if( plik.eof() || jakiznaknapotkano( plik ) == 3 || a == 1 )
        {
            cout << "if" << endl;
            suma += liczba;
            cout << "Suma w wierszu " << wiersz << " wynosi: " << suma << ". Przy liczbe bledow: " << suma_bledow << endl;
            suma = 0;
            wiersz++;
            suma_bledow = 0;
            a = 0;
        };
    }
    getch();
    plik.close();
    return 0;
}
Plik txt, na którym można rozpatrzeć wszystkie sytuacje.

1 a 2 55
1 d 2 3
2 3 132 87
2d3 2 4
a d
5
1 2 3d
1 2 d3
6
P-100535
pekfos
» 2013-12-29 17:20:06
Podaj 1 kod i opisz, co jest z nim nie tak.
P-100544
1 2 « 3 » 4
Poprzednia strona Strona 3 z 4 Następna strona