Program "Nazwa projektu".exe przestał działać po odpaleniu konsoli i wpisaniu wartości

0

Witam, mam problem odnośnie programu, gdzie po odpaleniu konsoli i wpisaniu wartości pojawia sie komunikat Program "Nazwa projektu".exe przestał działać. Po zamknięciu tego konsola zostaje i wszystko wylicza poprawnie z tego co zauważyłem, ale tylko do podania liczby z max. 10 cyfr, gdy podaje się liczbę z 11 cyfr już poprawnie nie wylicza.

Załączam kod (język C), nie mam pojęcia gdzie może być błąd. Z góry dziękuję za wszystkie odpowiedzi.


#include <stdio.h>
#include <stdlib.h>
#define DLUGOSC 1000
 
int ileCyfr(int x)
{
    int licznik=0;
 
    while(x!=0)
    {
        licznik++;
        x/=10;
    }
    return licznik;
}
 
int sumaCyfr(int x)
{
    int suma=0;
    while(x!=0)
    {
        suma+=x%10;
        x/=10;
    }
    return suma;
}
 
char* czyParzysta(int x)
{
    int i,reszta,n=ileCyfr(x);
    int tab[DLUGOSC];
 
    for(i=n-1;i>=0;i--)
    {
        reszta = x%10;
        tab[i]=reszta;
        x=x/10;
    }
 
 
    for(i=0;i<n;i++)
    {
 
    printf("%d - ",tab[i]);
 
        (tab[i]%2==0)?(printf("parzysta")):(printf("nieparzysta"));
        printf(", kwadrat = %d\n", kwadrat(tab[i]));
    }
 
}
 
int kwadrat(int x)
{
        return x * x;
}
 
int glowna(int a)
{
    printf("Podana liczba %d sklada sie z %d cyfr, a ich suma wynosi %d.\n",a,ileCyfr(a),sumaCyfr(a));
    printf("Kolejne cyfry:\n");
    printf("%s",czyParzysta(a));
    return 0;
}
 
int main()
{
    int n;
    printf("Podaj liczbe calkowita: ");
    scanf("%d",&n);
    glowna (n);
    return 0;
}



0

Ja to się zastanawiam jak Ci się to w ogóle kompilje skoro funkcję kwadrat używasz bez deklaracji ani definicji w użytym zakresie. A nie działa przy jedenastej liczbie ponieważ przekraczasz zakres typu int, nie zmieścisz w nim liczby złożonej z jedenastu cyfr.

0
several napisał(a):

Ja to się zastanawiam jak Ci się to w ogóle kompilje skoro funkcję kwadrat używasz bez deklaracji ani definicji.

Kompiluje mi sie do podania tylko cyfry z maksymalnie 10 cyfr tak jak napisałem w temacie, jak podam więcej wtedy już wylicza głupoty.

1

Podając liczbę jedenastocyfrową, Wychodzisz poza zakres integera:2147483647 (dziesięć cyfr), podając dziesięciocyfrową, czasem Wyjdziesz czasem nie.

1

Zacznij od poprawienia błędów, o których mówi kompilator, bo one wskazują na rzeczywiste problemy: https://wandbox.org/permlink/lDPlk5Eq7BO8lpNv

prog.c: In function 'czyParzysta':
prog.c:46:36: warning: implicit declaration of function 'kwadrat' [-Wimplicit-function-declaration]
   46 |         printf(", kwadrat = %d\n", kwadrat(tab[i]));
      |                                    ^~~~~~~
prog.c:49:1: warning: control reaches end of non-void function [-Wreturn-type]
   49 | }
      | ^

Np. czyParzysta zwraca char* (wtf?), ale nie ma w niej żadnej instrukcji return. To jest UB i bezsens. Swoją drogą, wspominasz o limicie 10 cyfr - używasz typu int, który z reguły ma zakres od -2147483648 do 2147483647. Jak chcesz większych to użyj int64_t, jakichś bigintów albo reprezentuj liczbę jako stringa.

0

Nie, nie kompiluje się. A dlaczego nie działa dla więcej niż dziesięc cyfr napisałem w poście wcześniej.

0

char* czyParzysta(int x)

Ta funkcja zwraca pointer na LOKALNĄ tablicę na stosie. Tak nie wolno. Ta tablica ci "zniknie" ze stosu po wyjściu z funkcji. Przy czym oczywiście sam stos jest re-użwany, więc jak przypadkiem nic ci tych danych nie nadpisze, to wartości nadal tam będą. Pewnie dla małych danych tak się akurat przypadkiem dzieje.

0
kq napisał(a):

Zacznij od poprawienia błędów, o których mówi kompilator, bo one wskazują na rzeczywiste problemy: https://wandbox.org/permlink/lDPlk5Eq7BO8lpNv

prog.c: In function 'czyParzysta':
prog.c:46:36: warning: implicit declaration of function 'kwadrat' [-Wimplicit-function-declaration]
   46 |         printf(", kwadrat = %d\n", kwadrat(tab[i]));
      |                                    ^~~~~~~
prog.c:49:1: warning: control reaches end of non-void function [-Wreturn-type]
   49 | }
      | ^

Np. czyParzysta zwraca char* (wtf?), ale nie ma w niej żadnej instrukcji return. To jest UB i bezsens. Swoją drogą, wspominasz o limicie 10 cyfr - używasz typu int, który z reguły ma zakres od -2147483648 do 2147483647. Jak chcesz większych to użyj int64_t, jakichś bigintów albo reprezentuj liczbę jako stringa.

A mógłbyś podpowiedzieć co mam poprawić, dopiero zaczynam programowanie od października i nie za bardzo się jeszcze orientuje.

0
several napisał(a):

Nie, nie kompiluje się. A dlaczego nie działa dla więcej niż dziesięc cyfr napisałem w poście wcześniej.

Zrobiłem tak że na koniec funkcji char czy parzysta dodałem return 0 , wstawiłem do kompilatora online i nie wykryło błędów przy czym zaznaczam że na początku w tym kompilatorze wykryto błąd ale w języku c++ natomiast gdy zmieniłem na sam c błedu już nie było. Co o tym sądzisz, jest to dobrze?

0
kq napisał(a):

Zacznij od poprawienia błędów, o których mówi kompilator, bo one wskazują na rzeczywiste problemy: https://wandbox.org/permlink/lDPlk5Eq7BO8lpNv

prog.c: In function 'czyParzysta':
prog.c:46:36: warning: implicit declaration of function 'kwadrat' [-Wimplicit-function-declaration]
   46 |         printf(", kwadrat = %d\n", kwadrat(tab[i]));
      |                                    ^~~~~~~
prog.c:49:1: warning: control reaches end of non-void function [-Wreturn-type]
   49 | }
      | ^

Np. czyParzysta zwraca char* (wtf?), ale nie ma w niej żadnej instrukcji return. To jest UB i bezsens. Swoją drogą, wspominasz o limicie 10 cyfr - używasz typu int, który z reguły ma zakres od -2147483648 do 2147483647. Jak chcesz większych to użyj int64_t, jakichś bigintów albo reprezentuj liczbę jako stringa.

Dodatkowo przesunąłem wyżej funkcje kwadrat nad funkcje czyparzysta

3

Dopiero od października? Dopiero? To znaczy, że miałeś cały kwartał na opanowanie podstaw! Zamiast naprawiać kod metodą losowego wstawiania literek i liczenia, że tym razem skompiluje się i kompilator nie wypluje warninga, zastanów się co ma się w tym kodzie dziać i doprowadź aby się działo. Dlaczego funkcja czyParzysta zwraca char*? Ma to sens? Jeśli ma, to dlaczego nie zwraca? Jeśli nie ma, to dlaczego nadałeś jej taką sygnaturę?

0

Już wiem jak to ogarnąć, dzięki za pomoc, z resztą sobie poradzę, temat do zamknięcia.

0

Zakres int:
od -2'147'483'648 do 2'147'483'647.
Wobec tego wprowadzając do zmiennej 11 cyfr wychodzisz poza zakres.

1 użytkowników online, w tym zalogowanych: 0, gości: 1