Problem z kodem C++ - weryfikacja numeru PESEL

Problem z kodem C++ - weryfikacja numeru PESEL
X8
  • Rejestracja:prawie 7 lat
  • Ostatnio:ponad 6 lat
  • Postów:3
0

Dzień dobry,

na zajęciach z architektury systemów komputerowych dostaliśmy kod programu C++ do weryfikacji numeru PESEL - mieliśmy go uruchomić na kompilatorze i przyjrzeć się strukturze kodu.

Niestety, po wprowadzeniu kodu do kompilatora, kod wyrzuca błędy, których nie potrafię zrozumieć i naprawić - będę wdzięczny za wszelką pomoc.

Kod programu:

Kopiuj
#include <stdio.h>
#include <stdlib.h>
 
short PESEL[11];
int valid = 0;
 
int getBirthYear() {
int year;
int month;
year = 10 * PESEL[0];
year += PESEL[1];
month = 10 * PESEL[2];
month += PESEL[3];
if (month > 80 && month < 93) {
year += 1800;
}
else if (month > 0 && month < 13) {
year += 1900;
}
else if (month > 20 && month < 33) {
year += 2000;
}
else if (month > 40 && month < 53) {
year += 2100;
}
else if (month > 60 && month < 73) {
year += 2200;
}
return year;
}
 
int getBirthMonth() {
int month;
month = 10 * PESEL[2];
month += PESEL[3];
if (month > 80 && month < 93) {
month -= 80;
}
else if (month > 20 && month < 33) {
month -= 20;
}
else if (month > 40 && month < 53) {
month -= 40;
}
else if (month > 60 && month < 73) {
month -= 60;
}
return month;
}
 
int getBirthDay() {
int day;
day = 10 * PESEL[4];
day += PESEL[5];
return day;
}
 
char* getSex() {
if (valid) {
if (PESEL[9] % 2 == 1) {
return "Mezczyzna";
}
else {
return "Kobieta";
}
}
else {
return "---";
}
}
 
int checkSum() {
int sum = 1 * PESEL[0] +
3 * PESEL[1] +
7 * PESEL[2] +
9 * PESEL[3] +
1 * PESEL[4] +
3 * PESEL[5] +
7 * PESEL[6] +
9 * PESEL[7] +
1 * PESEL[8] +
3 * PESEL[9];
sum %= 10;
sum = 10 - sum;
sum %= 10;
 
if (sum == PESEL[10]) {
return 1;
}
else {
return 0;
}
}
 
int checkMonth() {
int month = getBirthMonth();
if (month > 0 && month < 13) {
return 1;
}
else {
return 0;
}
}
 
int checkDay() {
int year = getBirthYear();
int month = getBirthMonth();
int day = getBirthDay();
if ((day >0 && day < 32) &&
(month == 1 || month == 3 || month == 5 ||
month == 7 || month == 8 || month == 10 ||
month == 12)) {
return 1;
}
else if ((day >0 && day < 31) &&
(month == 4 || month == 6 || month == 9 ||
month == 11)) {
return 1;
}
else if ((day >0 && day < 30 && leapYear(year)) ||
(day >0 && day < 29 && !leapYear(year))) {
return 1;
}
else {
return 0;
}
}
 
int leapYear(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
return 1;
else
return 0;
}
 
void PeselValidator(char *PESELNumber) {
int i;
 
if (strlen(PESELNumber) != 11){
valid = 0;
}
else {
for (i = 0; i < 11; i++){
PESEL[i] = PESELNumber[i] - 48;
}
if (checkSum() && checkMonth() && checkDay()) {
valid = 1;
}
else {
valid = 0;
}
}
}
 
void main(void)
{
char PESEL[200];
 
printf("Podaj numer PESEL\n");
scanf("%s", PESEL);
 
PeselValidator(PESEL);
 
if (valid == 1) {
printf("Numer PESEL jest prawidlowy\n");
printf("Rok urodzenia: %d\n", getBirthYear());
printf("Miesiac urodzenia: %d\n", getBirthMonth());
printf("Dzien urodzenia: %d\n", getBirthDay());
printf("Plec: %s\n", getSex());
}
else {
printf("Numer PESEL jest nieprawidlowy\n");
}
return;
}

Błędy wyrzucane przez kompilator:

Kopiuj
1) main.cpp: In function 'int checkDay()':
main.cpp:120:53: error: 'leapYear' was not declared in this scope
     else if(( day > 0 && day < 30 && leapYear( year ) ) ||
                                                     ^
2) main.cpp: In function 'void PeselValidator(char*)':
main.cpp:140:29: error: 'strlen' was not declared in this scope
     if( strlen( PESELNumber ) != 11 ) {
                             ^
3) main.cpp: At global scope:
main.cpp:156:17: error: '::main' must return 'int'
 void main( void )
                 ^
4) main.cpp: In function 'int main()':
main.cpp:175:5: error: return-statement with no value, in function returning 'int' [-fpermissive]
     return;
     ^

Uprzejmie proszę o wskazówki i pomoc - w jaki sposób naprawić ten kod?

Z góry dziękuję

edytowany 1x, ostatnio: flowCRANE
MY
Przede wszystkim popraw formatowanie kodu.
MY
  • Rejestracja:ponad 9 lat
  • Ostatnio:5 dni
  • Postów:1082
1
xardas88 napisał(a):
  1. main.cpp: In function 'int checkDay()':
    main.cpp:120:53: error: 'leapYear' was not declared in this scope

Oznacza nie mniej ni więcej, że kompilator nie wie co to za funkcja leapYear() po prostu musisz sobie ją napisać. Nie znam wszystkich funkcji na pamięć, ale C++ chyba nie posiada w standardzie takiej funkcji.

xardas88 napisał(a):
  1. main.cpp: In function 'void PeselValidator(char*)':
    main.cpp:140:29: error: 'strlen' was not declared in this scope

funkcja strlen akurat istnieje i musisz zaincludować string.h

xardas88 napisał(a):
  1. main.cpp: At global scope:
    main.cpp:156:17: error: '::main' must return 'int'

Jak sam komunikat wskazuje main musi zwracać typ int, a nie void.

xardas88 napisał(a):
  1. main.cpp: In function 'int main()':
    main.cpp:175:5: error: return-statement with no value, in function returning 'int' [-fpermissive]

jak wyżej main ma zwracać int'a, więc coś musi stać przy return. Najczęściej to będzie

Kopiuj
return 0;

Ogólnie pomijam, że to nie jest C++, a zwykłe C...

X8
  • Rejestracja:prawie 7 lat
  • Ostatnio:ponad 6 lat
  • Postów:3
0

Mr.YaHooo - dziękuję za odpowiedź.

W konsekwencji do Twoich dwóch ostatnich rad, poprawiłem kod na następujący:

Kopiuj
#include <stdio.h>
#include <stdlib.h>

short PESEL[ 11 ];
int valid = 0;

int getBirthYear() {
    int year;
    int month;
    year = 10 * PESEL[ 0 ];
    year += PESEL[ 1 ];
    month = 10 * PESEL[ 2 ];
    month += PESEL[ 3 ];
    if( month > 80 && month < 93 ) {
        year += 1800;
    }
    else if( month > 0 && month < 13 ) {
        year += 1900;
    }
    else if( month > 20 && month < 33 ) {
        year += 2000;
    }
    else if( month > 40 && month < 53 ) {
        year += 2100;
    }
    else if( month > 60 && month < 73 ) {
        year += 2200;
    }
    return year;
}

int getBirthMonth() {
    int month;
    month = 10 * PESEL[ 2 ];
    month += PESEL[ 3 ];
    if( month > 80 && month < 93 ) {
        month -= 80;
    }
    else if( month > 20 && month < 33 ) {
        month -= 20;
    }
    else if( month > 40 && month < 53 ) {
        month -= 40;
    }
    else if( month > 60 && month < 73 ) {
        month -= 60;
    }
    return month;
}

int getBirthDay() {
    int day;
    day = 10 * PESEL[ 4 ];
    day += PESEL[ 5 ];
    return day;
}

char * getSex() {
    if( valid ) {
        if( PESEL[ 9 ] % 2 == 1 ) {
            return "Mezczyzna";
        }
        else {
            return "Kobieta";
        }
    }
    else {
        return "---";
    }
}

int checkSum() {
    int sum = 1 * PESEL[ 0 ] +
    3 * PESEL[ 1 ] +
    7 * PESEL[ 2 ] +
    9 * PESEL[ 3 ] +
    1 * PESEL[ 4 ] +
    3 * PESEL[ 5 ] +
    7 * PESEL[ 6 ] +
    9 * PESEL[ 7 ] +
    1 * PESEL[ 8 ] +
    3 * PESEL[ 9 ];
    sum %= 10;
    sum = 10 - sum;
    sum %= 10;
    
    if( sum == PESEL[ 10 ] ) {
        return 1;
    }
    else {
        return 0;
    }
}

int checkMonth() {
    int month = getBirthMonth();
    if( month > 0 && month < 13 ) {
        return 1;
    }
    else {
        return 0;
    }
}

int checkDay() {
    int year = getBirthYear();
    int month = getBirthMonth();
    int day = getBirthDay();
    if(( day > 0 && day < 32 ) &&
    ( month == 1 || month == 3 || month == 5 ||
    month == 7 || month == 8 || month == 10 ||
    month == 12 ) ) {
        return 1;
    }
    else if(( day > 0 && day < 31 ) &&
    ( month == 4 || month == 6 || month == 9 ||
    month == 11 ) ) {
        return 1;
    }
    else if(( day > 0 && day < 30 && leapYear( year ) ) ||
    ( day > 0 && day < 29 && !leapYear( year ) ) ) {
        return 1;
    }
    else {
        return 0;
    }
}

int leapYear( int year ) {
    if( year % 4 == 0 && year % 100 != 0 || year % 400 == 0 )
         return 1;
    else
         return 0;
    
}

void PeselValidator( char * PESELNumber ) {
    int i;
    
    if( strlen( PESELNumber ) != 11 ) {
        valid = 0;
    }
    else {
        for( i = 0; i < 11; i++ ) {
            PESEL[ i ] = PESELNumber[ i ] - 48;
        }
        if( checkSum() && checkMonth() && checkDay() ) {
            valid = 1;
        }
        else {
            valid = 0;
        }
    }
}

int main( void )
{
    char PESEL[ 200 ];
    
    printf( "Podaj numer PESEL\n" );
    scanf( "%s", PESEL );
    
    PeselValidator( PESEL );
    
    if( valid == 1 ) {
        printf( "Numer PESEL jest prawidlowy\n" );
        printf( "Rok urodzenia: %d\n", getBirthYear() );
        printf( "Miesiac urodzenia: %d\n", getBirthMonth() );
        printf( "Dzien urodzenia: %d\n", getBirthDay() );
        printf( "Plec: %s\n", getSex() );
    }
    else {
        printf( "Numer PESEL jest nieprawidlowy\n" );
    }
    return 0;
}

I istotnie - 2 błędy mniej.
W dalszym ciągu jednak nie wiem co zrobić z problemem odnośnie leapYear() oraz strlen (co oznacza "zaincludowanie" string.h?) - będę wdzięczny za dalsze wskazówki.

Nie ukrywam że jestem laikiem - nauczycielka przedmiotu ani razu nie pojawiła się na zajęciach, kontaktuje się z nami wyłącznie mailowo i generalnie chyba nie bardzo chce nas nauczyć - zakłada że to już umiemy, a tymczasem praktycznie nikt nic na temat C++ nie wie.
Staram się czytać różnego rodzaju kursy i oglądać tutoriale, ale w dalszym ciągu jestem zielony (a chciałbym jednak choć trochę to zrozumieć).

edytowany 1x, ostatnio: flowCRANE
MY
  • Rejestracja:ponad 9 lat
  • Ostatnio:5 dni
  • Postów:1082
0
xardas88 napisał(a):

co oznacza "zaincludowanie" string.h?

Po prostu na początku pliku powinieneś dodać linijkę:

Kopiuj
#include <string.h>

Jak ją dodasz kompilator powinien wiedzieć co to strlen

xardas88 napisał(a):

W dalszym ciągu jednak nie wiem co zrobić z problemem odnośnie leapYear()

Mój błąd funkcję masz zdefiniowaną, tylko, że jest ona jako 8, a wykorzystywana jest w poprzedniej checkDay Kompilator nie je wieszcze analizując funkcję checkDay, że coś takiego jak leapYear istnieje i temu się pruje. Powinieneś zmienić kolejność funkcji. Kawałek

Kopiuj
int leapYear( int year ) {
    if( year % 4 == 0 && year % 100 != 0 || year % 400 == 0 )
         return 1;
    else
         return 0;

}

Możesz przenieść jako pierwszą funkcję i będzie ok.

Tak ogólnie to najlepiej by było aby nauczycielka na początku zadeklarowała funkcje dając na początku tak:

Kopiuj
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

short PESEL[ 11 ];
int valid = 0;

int getBirthYear();
int getBirthMonth();
int getBirthDay();
char * getSex();
int checkSum();
int checkMonth();
int checkDay();
int leapYear( int year );
void PeselValidator( char * PESELNumber )



 int getBirthYear(){
 .
 .
 .
 .
 .

Wtedy nie było by problemu z kolejnością funkcji w pliku źródłowym. Dodatkowo można by wyeliminować zmienne globalne. Ale to już temat na dłuższą pogawędkę :)

X8
  • Rejestracja:prawie 7 lat
  • Ostatnio:ponad 6 lat
  • Postów:3
0

Mr.YaHooo - super, bardzo dziękuję za pomoc :)

Istotnie, kod teraz działa :)

Pomyślę teraz o tym, jak faktycznie nieco oczyścić i zoptymalizować kod i ew. dodać coś ciekawego :) - w razie problemów pozwolę sobie jeszcze tutaj napisać :)

Jeszcze raz bardzo dziękuję.

flowCRANE
Doceniaj pomocne posty – niech będzie wiadomo, że są pomocne.
MY
  • Rejestracja:ponad 9 lat
  • Ostatnio:5 dni
  • Postów:1082
0

@xardas88 nie ma za co, jakby co pytaj :)

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)