Dziwne zachowanie wskaźników w prostej bazie danych opartej o strukturę.

0

Witam!

Piszę program, który ma przyjąć formę czegoś na kształt książki telefonicznej.
Całość oparta jest o prostą strukturę zawierającą numer porządkowy, imię, nazwisko i telefon.
Program poprawnie wczytuje dane do struktury dla kilku osób, poprawnie je potem wyświetla. Problem w tym, że mam ambicję od razu sprawdzić, czy ktoś nie wprowadził błędnych danych, na przykład imienia w formie K4zyszt0f. Sęk w tym, że wskaźniki pokazujące na imię i nazwisko w strukturze zachowują się tak, jakby w tablicach znaków przechowujących imię i nazwisko były jakieś całkowicie losowe znaki, przez co cały program się sypie. Kompilator nie wyrzuca żadnych błędów, ale program nie działa prawidłowo. Dorzucam od razu SS z działania programu.

 
#include <iostream>
#include <string.h>
#include <cstdlib>
using namespace std;

struct dane
{
    int numer;
    char imie[20];
    char nazwisko[20];
    long long telefon;
};

bool sprawdzam_imie (char imie)
{
        if ((imie >= 'A' && imie <= 'Z') || (imie >= 'a' && imie <= 'a'))
            return true;
        else
            return false;
}

bool sprawdzam_nazwisko (char nazwisko)
{
        if ((nazwisko >= 'A' && nazwisko <= 'Z') || (nazwisko >= 'a' && nazwisko <= 'z'))
            return true;
        else
            return false;
}

void uzupelnij (dane osoba[], int n)
{
    dane *wsk = &osoba[20];

    for (int i=0; i<n; i++)
    {
        int k=i+1;
        cout << "\nOsoba numer " << k << endl;

        cout << "Podaj imie: ";
        cin >> osoba[i].imie;
        int x = strlen(osoba[i].imie);
        int q = 0;

        while (wsk->imie[q] != '/0')
        {
            if (sprawdzam_imie(wsk->imie[q]) == false)
            {
            cout << "Cos jest nie tak! Sprobuj jeszcze raz!" << endl;
            cout << wsk->imie[q] << " to nie litera!" << endl;
            break;
            }
            else
                wsk->imie[q]++;
        }

        cout << "Podaj nazwisko: ";
        cin >> osoba[i].nazwisko;
        int y = strlen(osoba[i].nazwisko);
        int w = 0;

        while (wsk->nazwisko[w] != '/0')
        {
            if (sprawdzam_nazwisko (wsk->nazwisko[w]) == false)
            {
            cout << "Cos jest nie tak! Sprobuj jeszcze raz!" << endl;
            cout << wsk->nazwisko[w] << " to nie litera!" << endl;
            break;
            }
            else
                wsk->nazwisko[w]++;
        }

        cout << "Podaj telefon: ";
        cin >> osoba[i].telefon;
    }
}

void wyswietl (dane osoba[], int n)
{
    cout << "\nOsoba numer " << n+1 << ":" << endl;
    cout << "Imie: " << osoba[n].imie << endl;
    cout << "Nazwisko: " << osoba[n].nazwisko << endl;
    cout << "Tel.: " << osoba[n].telefon << endl;
}

int main()
{
    dane osoba[20];
    int i, ileOsob;

    cout << "Podaj ilosc osob: ";
    cin >> ileOsob;

    uzupelnij (osoba, ileOsob);

    cout << "\nDane osob w bazie: " << endl;

    for (i=0; i<ileOsob; i++)
    {
        wyswietl(osoba, i);
    }
}

user image

Problem jest o tyle dziwny, że dużo prostszy program, ale oparty na tej samej zasadzie, działa bez zarzutu:

 
#include <iostream>
#include <string.h>
using namespace std;

struct test
{
    int liczba;
    char znaki[20];
};

int main()
{
    test dane;
    test * wskaznik =& dane;

    cout << "Podaj wartosc liczby: ";
    cin >> dane.liczba;
    cout << "Podaj znaki: ";
    cin >> dane.znaki;

    cout << "\nWartosc liczby: " << wskaznik->liczba << endl;
    cout << "Twoj znak: " << wskaznik->znaki << endl;
    cout << "Dlugosc lancucha znakow: " << strlen(dane.znaki) << endl;

    return( 0 );
}
1

Mazesz po nie swojej pamieci
przy osoba[20] pierwsza indeks 0, a ostatnia 19.

1

Tablica dane osoba[20] przyjmuje indeksy od [0] do [19], a ty używasz w jednym miejscu indeksu [20].

1

No i:
1.(imie >= 'a' && imie <= 'a')
2.'/0' - ukośnik w drugą stronę: \0,
3.Numer telefonu zapisuj jako ciąg znaków.
4.void wyswietl (dane osoba[], int n) - dlaczego po prostu nie przyjmiesz jako argument dane osoba? :|
5.wsk->imie[q]++; a to to w ogóle co jest.
6.void uzupelnij (dane osoba[], int n) to samo, co podpunkt czwarty. Tyle że tutaj musisz przyjmować wskaźnik.

0

Dziękuję za szybką odpowiedź, poprawiłem wskazane przez Was błędy. Teraz wszystko działa jak należy.

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