• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

SPOJ - Formularz (błąd wykonania)

Object Storage Arubacloud
0 głosów
257 wizyt
pytanie zadane 20 lutego 2021 w C i C++ przez Billy Użytkownik (680 p.)
edycja 21 lutego 2021 przez Billy

Hejka,

Robiłem zadanie ze SPOJa: https://pl.spoj.com/problems/KC005 
i utknąłem. Dla przykładowych danych program działa super, ale jak puszczam do sprawdzenia, to dostaję błąd wykonania (SIGABRT). Z tego co gdzieś usłyszałem, błąd jest powodowany przez to, że np. odwołujemy się do nieistniejącej szufladki itp. Przeglądając mój kod jednak nie znalazłem niczego takiego. Poniżej zamieszczam kod:

#include <iostream>

using namespace std;

int main()
{
    string II, NN, DATE, x;
    while(cin>>x>>II>>x>>NN>>x>>x>>DATE)
    {

    //IMIE
        if(II[0]>=65 && II[0]<=90 && II.length()<=11)
        {
            for(int i=1; i<II.length()-1; i++)
            {
                if(II[i]<97 || II[i]>122)
                {
                    goto x;
                    continue;
                }
            }
        }
        else
        {
            x:
            cout<<0<<endl;
            continue;
        }
    //NAZWISKO
        if(II[0]>=65 && II[0]<=90 && NN.length()<=21)
        {
            for(int i=1; i<NN.length()-1; i++)
            {
                if(NN[i]<97 || NN[i]>122)
                    goto y;
            }
        }
        else
        {
            y:
            cout<<1<<endl;
            continue;
        }
    //DATA - ROZDZIELENIE
        bool f1=0,f2=0;
        string RRRR,MM,DD;
        for(int i=0; i<10; i++)
        {
            if(DATE[i]=='-' && f1==0) {f1=1; i++;}
            else if(f1==0) {RRRR+=DATE[i]; continue;}

            if(DATE[i]=='-' && f1==1 && f2==0) {f2=1; i++;}
            else if(f1==1 && f2==0) {MM+=DATE[i]; continue;}

            DD+=DATE[i];
        }
    //DATA - WARUNKI
        if(RRRR=="" || MM=="" || DD==""
           || stoi(RRRR)>2000 || stoi(RRRR)<1900 || stoi(MM)>12 || stoi(MM)<1 || stoi(DD)<1 || stoi(DD)>31)
        {
            cout<<2<<endl;
            continue;
        }
    //INNE PRZYPADKI
        cout<<3<<endl;

    }
    return 0;
}

Dla wyjaśnienia te "x" które wczytuję, to po prostu zapychacz, żeby pominąć w jakiś sposób te nagłówki( "imie: " itp.).
Jaki tu może być błąd? I dla jakich jeszcze przypadków może wystąpić błąd wykonania?

komentarz 25 lutego 2021 przez j23 Mędrzec (194,920 p.)
Być może podana data nie zawsze jest w formie czterech znaków na rok i po dwa na miesiąc i dzień. Wtedy ten twój pierwotny kod gmera poza zakresem stringa, co oczywiście musi skończyć się źle.
komentarz 25 lutego 2021 przez Billy Użytkownik (680 p.)
edycja 25 lutego 2021 przez Billy

Właśnie problem, że tam nie ma niczego do gmerania. Nie sięgam nawet do żadnej szufladki z tego stringa:

#include <iostream>
#include <istream>
 
using namespace std;
 
istream& readRecord (istream &is, string &II, string &NN, string &RRRR, string &MM, string &DD)
{
    getline(cin.ignore(666, ':') >> ws, II, ';');
    getline(cin.ignore(666, ':') >> ws, NN, ';');
 
    getline(cin.ignore(666, ':') >> ws, RRRR, '-');
    getline(cin, MM, '-');
    getline(cin, DD);
    return is;
}

/* .... */

//DATA - WARUNKI
    if(RRRR=="" || MM=="" || DD==""
        || stoi(RRRR)>2000 || stoi(RRRR)<1900 || stoi(MM)>12 || stoi(MM)<1 || stoi(DD)<1 || stoi(DD)>31)
    {
        cout<<2<<endl;
        continue;
    }

To mój poprzedni kod, który jeszcze nie działał - wczytałem datę jako całe słowo i zrobiłem te sprawdzanie od ciebie - wszystko działa

P.S. Od razu powiem, że wczytywanie działa idealnie - sprawdzałem poprzez wypisywanie i wszystko wygląda dobrze dla tych testów

1
komentarz 26 lutego 2021 przez j23 Mędrzec (194,920 p.)

Właśnie problem, że tam nie ma niczego do gmerania.

Pisałem o kodzie, który podałeś na samym początku.

stoi rzuci wyjątkiem, jeśli nie będzie mogło przeprowadzić konwersji. Możliwe, że to jest powodem.

P.S. w readRecord masz cin zamiast is.

 

komentarz 26 lutego 2021 przez Billy Użytkownik (680 p.)

stoi rzuci wyjątkiem, jeśli nie będzie mogło przeprowadzić konwersji. Możliwe, że to jest powodem

Myślałem, że jestem mądry, bo przed użyciem tej funkcji sprawdziłem, czy jest puste. Ale jak się przekonałem np. "_10" wyrzuca błąd. Wkurzyłem się więc, i dopiero wtedy zauważyłem, że atoi  robi to samo tylko lepiej. Więc wrzuciłem ją tam, i wszystko zadziałało. W sensie nie wyrzuciło błędu "błąd wykonania", tylko "błędna odpowiedź".
 

I teraz już nie wiem co jest błędne (to, że jak jest spacja przed "-" (np. "1900- 10-10) to nie powinno zaliczać czy jak? już chyba za dużo czasu poświęciłem na to zadanie, a to co najważniejsze się dowiedziałem (czyli dlaczego w ogóle nie działało) no i parę dodatkowych informacji i wskazówek dzięki tobie :P)

A co do readRecord to cin  działa zamiast is (bo zaakceptował rozwiązanie z twoim wczytywaniem daty) (zmienię na wszelki wypadek).  Aczkolwiek nie wiem niestety nadal jak to działa i co to właściwie jest (ta dokumentacja nie wiele mi wyjaśniła). (Chodzi o to, że tworzymy obiekt na podobieństwo cin i korzystamy z niego w ten sam sposób?) Być może jestem na jeszcze zbyt niskim poziomie, żeby to zrozumieć :/

komentarz 26 lutego 2021 przez j23 Mędrzec (194,920 p.)

Chodzi o to, że tworzymy obiekt na podobieństwo cin i korzystamy z niego w ten sam sposób?my obiekt na podobieństwo cin i korzystamy z niego w ten sam sposób?

Nie. is to referencja do strumienia, z którego mają być czytane dane. Jak przy wywołaniu readRecord dasz std::cin, to będzie czytać ze standardowego wejścia, a jak dasz strumień plikowy (obiekt klasy std::ifstream), to będzie czytać z pliku. Tu wykorzystywany jest polimorfizm, dzięki czemu funkcja nie jest uzależniona od jednego źródła danych.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 102 wizyt
pytanie zadane 5 lipca 2022 w C i C++ przez polandonion Mądrala (7,040 p.)
+1 głos
3 odpowiedzi 1,948 wizyt
pytanie zadane 17 czerwca 2016 w C i C++ przez niezalogowany
+1 głos
1 odpowiedź 129 wizyt
pytanie zadane 4 września 2022 w Java przez Aragedens Obywatel (1,120 p.)

92,576 zapytań

141,426 odpowiedzi

319,650 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...