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

Błąd wykonanania (SIGABRT) zadanie "Suma" Polski SPOJ

Object Storage Arubacloud
+1 głos
1,448 wizyt
pytanie zadane 19 czerwca 2016 w C i C++ przez ernest52 Początkujący (450 p.)
Witam !

Mam  problem, robiłem zadanie "Suma" z Polskiego Spoja , link do zadania: http://pl.spoj.com/problems/SUMA/

A to mój kod do niego:

#include <iostream>
using namespace std;
int main()
{
    cout<<"ile liczb chcesz zsumowac:  ";
    int ile;
    cin>>ile;
    int *tab;
    tab=new int[ile];
    for(int i=0;i<ile;i++)
    {
        cout<<"podaj liczbe "<<i+1<<":  ";
        cin>>tab[i];
        
    }
    for(int i=0;i<ile;i++)
    {
        if(i>0)
        {
            tab[i]+=tab[i-1];
        }
        cout<<tab[i]<<endl;
    }
    
    delete [] tab;
    
    return 0;
    
}

 

Ogólnie chodzi w konsoli, ale jak próbowałem wrzucić to do sędziego to wyskoczył mi błąd "SIGABRT" . Co on oznacza? Co tu jest źle? (oczywiście cout-y nie wysyłałem do sędziego usunąłem je)
komentarz 19 czerwca 2016 przez draghan VIP (106,230 p.)

Czy kolega zapoznał się z regulaminem, zanim umieścił pytanie? Albo chociaż przeczytał wskazówki do zadawania pytań, które umieszczone są nad formularzem pytania?

http://forum.pasja-informatyki.pl/90416/spoj-zasady-umieszczania-postow?show=90416#q90416

2 odpowiedzi

+3 głosów
odpowiedź 19 czerwca 2016 przez CharlieGG Użytkownik (900 p.)
edycja 19 czerwca 2016 przez CharlieGG

Czytaj dokładnie treść zadań: "Na wejście programu podana zostanie pewna nieokreślona, ale niewielka ilość małych liczb całkowitych". Na wejściu nie jest podana ilość liczb, więc musisz zastosować sposób, który wczytuje wszystko z pliku aż do jego końca, czyli do wskaźnika EOF. Można to zrobić na kilka sposobów:

1) Używając iostream: 

    while( cin >> tab[ile] )
    {
    	ile++;
    }
    
    //ewentualnie skrócona wersja
    while( cin >> tab[ile++] );

2) używając cstdio:

    //sposób 1
    while( scanf( "%d", &tab[ile] ) != EOF )
    {
    	ile++;
    }
    //krótsza wersja
    while( scanf( "%d", &tab[ile++] ) );
    
    //sposób 2
    while( ~scanf( "%d", &tab[ile] ) )
    {
    	ile++;
    }
    //krótsza wersja
    while( ~scanf( "%d", &tab[ile++] ) );

Rozdzieliłem na krótsze i dłuższe wersje, bo nie wiem czy zrozumiesz jak działa inkrementacja w takim przypadku, ale polecam się tego nauczyć, bo często ułatwia to życie. Oczywiście używając takiego wczytywania danych, nie musisz dzielić kodu na 2 części tj. wczytanie liczb i obliczanie kolejnych sum, ale możesz to wszystko zrobić wszystko w jednej pętli (tej w której wczytujesz), ale jak to zrobić to już zostawię dla Ciebie jako ćwiczenie :)

Zapomniałem jeszcze o jednej bardzo ważnej rzeczy, a mianowicie o tym, że jeśli nie znasz ilości liczb na wejściu to nie możesz zainicjalizować wcześniej tablicy w sposób new int[ile]. Rozwiązaniem tego problemu jest wcześniejsze zainicjalizowanie tablicy z góry ustalonym rozmiarem, który na pewno zmieści wszystkie liczby czyli np. int tab[1000]. Ewentualnie w ogóle można zrobić to zadanie bez używania tablicy, ale tak jak wcześniej, zostawię to jako ćwiczenie :)

komentarz 19 czerwca 2016 przez ernest52 Początkujący (450 p.)
edycja 19 czerwca 2016 przez ernest52
Dzięki za drugi akapit Twojej odpowiedzi bo już miałem pytać o to :

int ile=0;
    int tab[ile]//teraz wpisałem tu 1000;
    while(cin>>tab[ile])
    {
            if(ile!=0)
            {
                tab[ile]+=tab[ile-1];
            }
            cout<<tab[ile]<<endl;
            
    
    
        ile++;
        
    }

choć przeczuwałem, że to błędne bo kompilator musi wiedzieć ile tablica będzie miała elementów.. ok to już w sumie wiem jak to działa (nie wyjdę z while dopóki nie wczytam 1000 liczb), ale czy 1000 to nie za dużo? Co to w ogóle oznacza " nie wielka liczba"? W końcu dla jednych nie wiele to 1zł a dla innych 100zł ;p. Skoro i tak trzeba ustalić tą mniejszą liczbę to czy wystarczyłby zwykły for ?

Ta drugi sposób to dwie zmienne np a i b:

int a,b;
    a=b=0;
    for(int i=0;;i++)
    {
        cin>>a;
        a+=b;
        cout<<a<<endl;
        cin>>b;
        b+=a;
        cout<<b<<endl;
    }

Tylko dalej nie mam zielonego pojęcia ile ma iteracji mają trwać instrukcje? I jak by tu wyglądał ten sposób na EOF? While(cin>>a) ?
komentarz 19 czerwca 2016 przez CharlieGG Użytkownik (900 p.)
Co do pojęcia "niewielka" to nigdzie nie ma z tego góry określonego, ale znając standardy SPOJa to autorzy mają w takich przypadkach namyśli liczby wielkości około 100, a nawet mniejsze, więc 1000 spokojnie wystarczy.

Co do samego wczytywanie, to źle zrozumiałeś. Pętla nie będzie wczytywała dopóki nie wypelni calej tablicy (bo chyba tak zrozumiales), ale po prostu, gdy będzie wczytywała dane z pliku (a w taki sposob, wczytywane sa testy na spoju), to na końcu każdego pliku jest znak EOF (End Of File), który oznacza, iż w pliku już nic więcej nie ma i w takim przypadku, funkcja wczytująca dane (cin/scanf) odpowiednio na to zareaguje i umozliwi wyjscie z petli.

Jeśli chodzi o drugi sposób to nie rozumiem o co ci chodzi z "mniejszą liczbą", ale zobacz że w Twoim podejściu, przy każdej iteracji wczytujesz 2 liczby, czyli ilość wczytanych liczb zawsze będzie parzysta, a co w przypadku gdy ta ilość będzie nieparzysta? No właśnie klapa. Powinieneś wczytywać po jednej liczbie z wejścia na jeden obrót pętli i możesz to zrobić tak jak napisałeś czyli while(cin >> a). Co do fora to pewnie jakoś się da, ale raczej nie byłoby to zbyt estetyczne, a też nie ma co zbytnio kombinować jeśli używając whila wychodzi nam to szybko, ładnie i przyjemnie.
komentarz 20 czerwca 2016 przez ernest52 Początkujący (450 p.)
Ok teraz już wiem jak to działa , co to jest ten EOF i gdzie on się znajduje. Dzięki za wytłumaczenie ,za pomoc i za cierpliwość. Zrobiłem to sumowanie i zadanie z równań kwadratowych,które również opierało się na EOF. Teraz będę wiedział jak się odnieść do zadań tego typu i jak sobie z nimi radzić. Jeszcze raz wielkie dzięki.
komentarz 20 czerwca 2016 przez ernest52 Początkujący (450 p.)
dobra mam jednak jeszcze jedno pytanie: Czy warunek pętli może być rozwinięty to znaczy może być tak while((cin>>tab[i++])&&(i<10)); czy tylko while(cin>>tab[i++]); po za tym kiedy funkcja cin , która jest w while dostaje znak EOF, to pętla zostaje zakończona i wykonują się instrukcje , które są poniżej, dobrze rozumiem?
komentarz 20 czerwca 2016 przez CharlieGG Użytkownik (900 p.)
Pętla while przerywa działanie, gdy jej warunek przyjmie wartość false, o innym sposobie przerwania pętli w warunku nie słyszałem. Idąc tym tropem możemy wywnioskować, że w przypadku wczytania EOF funkcja wczytująca po prostu zwraca 0, przez co pętla jest przerywana. Nie wiem o co chodzi z "instrukcjami poniżej", ale jeśli pętla się przerwie to siłą rzeczy nie wykonają się instrukcje w pętli i program przejdzie do następnych instrukcji spoza pętli.
komentarz 20 czerwca 2016 przez ernest52 Początkujący (450 p.)
mam kolejne pytanie ;p (sorry ,jak będziesz mieć mnie dość to nie odpisuj ;p) mam kod:

int i=0, tab[10];
    while((cin>>tab[i++])&&(i<10))
    {
            
        
    }
    --i;
    
    while((cout<<tab[i--]<<" ")&&(i>=0));

Czy on jest dobry(działa, w okienku wczytuje liczby a następnie wypisuje je w odwrotnej kolejności), ale na SPOJ-u pisze o błędzie, skoro działa mi w okienku cmd to teoretycznie na SPOJ-u też powinien działać a tak nie jest. Czy wynika to przez źle stworzone pętle, czy nie będzie ten kod działał dla EOF? Gdybyś był zaciekawiony treścią zadania: http://pl.spoj.com/problems/TABLICA/ . Nie chcę Cię męczyć z każdym zadaniem , nawet nie tym po prostu nie jestem pewny jak się tworzy tablice by działały dla EOF, czy ta zdefiniowana przeze mnie  jest napisana poprawnie? Czy pętle są napisane poprawnie (nie chodzi mi czy rozwiązują zadanie, ale czy nie są źle skonstruowane bo np. przez EOF nie mogę zrobić tak czy tak) . Jeżeli są poprawnie napisane to po prostu błąd wynika z faktu, że czegoś nie przewidziałem i muszę to przemyśleć jeszcze raz , ale chcę wiedzieć czy  nie jest to błąd spowodowany EOF tym ,że SPOJ odczytuje testy z pliku, a ja robię w cmd. Jeżeli tak jest to jak te błędy mam naprawić?
komentarz 21 czerwca 2016 przez CharlieGG Użytkownik (900 p.)
A jakiego rodzaju błąd Ci SPOJ wywala? Jeśli błędną odpowiedź to po prostu czegoś nie rozważasz i jeśli tak to myślę, że ograniczenie i do 10 jest za małe, bo te "niewiele" jak pisałem może być do 100 albo i 1000 nawet.
+1 głos
odpowiedź 19 czerwca 2016 przez MetRiko Nałogowiec (37,110 p.)

Spróbuj skomentować te dwie linie i zobacz czy błąd dalej wywala:

cout<<"ile liczb chcesz zsumowac:  ";
cout<<"podaj liczbe "<<i+1<<":  ";

Spoj w zadaniach nie bez powodu podaje wejście i wyjście.. dokładnie w ten sam sposób muszą one wyglądać w konsoli.
Nie wymagane jest informowanie w programie co należy wprowadzić ponieważ "sędzia" dokładnie wie co ma być na wejściu i wyjściu. Nie gwarantuję, że to rozwiąże problem.. ale na pewno ta wiedza ci się przyda.

Podobne pytania

+1 głos
1 odpowiedź 502 wizyt
pytanie zadane 17 lipca 2022 w Java przez Ada3141592654 Początkujący (270 p.)
0 głosów
0 odpowiedzi 398 wizyt
pytanie zadane 15 marca 2022 w C i C++ przez Zielnik Nowicjusz (120 p.)
0 głosów
0 odpowiedzi 1,242 wizyt
pytanie zadane 26 stycznia 2016 w C i C++ przez Avalon Obywatel (1,130 p.)

92,568 zapytań

141,422 odpowiedzi

319,635 komentarzy

61,956 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!

...