scanf kasuje czy znowu złe parametry?

0

Taki oto kodzik:
typedef struct TElement
{
char Nazwisko[20], Imie[20];
unsigned char Grupa, NrProjektu, PktZdobyte, PktMozliwe;
Data DataOddania;
struct TElement *Nast;
} *PLista;

void ModEl(PLista El)
/* Modyfikuje element listy */
{
int r, m, d;

printf("Nazwisko: %s\n", El->Nazwisko);
printf("Podaj nazwisko\n");
fflush(stdin);
scanf("%s", El->Nazwisko);
printf("Imie: %s\n", El->Imie);
printf("Podaj imi©\n");
fflush(stdin);
scanf("%s", El->Imie);
printf("Grupa: %u\n", El->Grupa);
printf("Podaj grup©\n");
fflush(stdin);
scanf("%u", &(El->Grupa));
printf("Nr projektu: %u\n", El->NrProjektu);
printf("Podaj nr projektu\n");
fflush(stdin);
scanf("%u", &(El->NrProjektu));
printf("Zdobyte punkty: %u\n", El->PktZdobyte);
printf("Podaj liczb© zdobytych punkt˘w\n");
fflush(stdin);
scanf("%u", &(El->PktZdobyte));
printf("Punkty moľliwe do zdobycia: %u\n", El->PktMozliwe);
printf("Podaj liczb© punkt˘w moľliwych do zdobycia\n");
fflush(stdin);
scanf("%u", &(El->PktMozliwe));
printf("Data oddania projektu: %u-%u-%u\n", El->DataOddania.r, El->DataOddania.m, El->DataOddania.d);
printf("Podaj rok, w kt˘rym projekt zosta oddany\n");
scanf("%u", &r);
printf("Podaj miesiĄc, w kt˘rym projekt zosta oddany\n");
scanf("%u", &m);
printf("Podaj dzieä, w kt˘rym projekt zosta oddany\n");
scanf("%u", &d);
El->DataOddania.r = r;
El->DataOddania.m = m;
El->DataOddania.d = d;
}

I wszystko byłoby pięknie, ale jak już uzupełniam dane dla Nr projektu, to kasuje mi następne (dokładniej zeruje). Czy podaję złę parametry w scanf? (%ud też próbowałem).

0

Sprawdziłem i wygląda to tak:
scanf gdy ma format "%u" lub "%ud" to do nastepnego parametru wpisuje 4 bajty (DW). Jako, że NrProjektu, PktZdobyte, PktMozliwe i DataOddania.r są zaraz po sobie i mają po jednym bajcie to wpisuje tam zera (albo co innego, zależy jak dużą liczbą jest NrProjektu). Wystarczy zmienić typ char na int lub unsigned.

0

zmien unsigned char na char i potem w scanfie ładuj po %c
albo cin >> zmienna , ale to tylko w c++
lub laduj zmianna=getchar()

0

zmien unsigned char na char i potem w scanfie ładuj po %c
albo cin >> zmienna , ale to tylko w c++
lub laduj zmianna=getchar()

Tylko, że %c wczytuje znak. Jeżeli wpiszę 21 to mi wczyta 2 :)
Ale już sobie z tym poradziłem. Użyłem zmiennej pomocniczej. A unsigned char było konieczne (no, przynajmniej przydatne).
Embaraced za to wytłumaczył przyczynę.

0

Tylko, że %c wczytuje znak. Jeżeli wpiszę 21 to mi wczyta 2 :)
Ale już sobie z tym poradziłem. Użyłem zmiennej pomocniczej. A unsigned char było konieczne (no, przynajmniej przydatne).
Embaraced za to wytłumaczył przyczynę.

no ale jak sama nazwa wskazuje (unsigned)char to znak ;)
ale jak chcesz liczbe , to sproobuj wczytac tez inta %d , a potem konwertowac na unsigned char

0

scanf to bardzo niewdzięczna funkcja i radzę uduczyć ci się jej stosowania.
Jak jusz wcześniej pisali lepiej to wykonać an getch,getche.
Jaki popełniłś błędy w tym programie:
Po pierwszw dałeś na imię i nazwisko stały rozmiar pola a nie zabezpieczyłeś przed jego przekroczeniem i będziesz miał kłopoty jeżeli ktoś ma długie nazwisko np dwuczłonowe i przekroczy rozmiar pola i wejdzie ci na imię a potem imię zapiszesz i co może ci wyświetlić część nazwiska z imieniem.
Druga żecz jest taka że musisz pamiętać o wielkościach danego typu i w zależności od kompilatora na jakim siądziesz sprawdzić sobie wielkość danych typów.
sizeof(int),sizeof(char)itd.
unsigned rózni się tym od signed że ostatni najstarszy bit tego słowa jest bitem znaku i tak dla czar signed -128do 127 a unsigned od 0 do 255. Standardowe znaki mieszczą się do 127 to więc do przechowywanie jakiś znaczkuw to jest twoja decyzja.
/__________________
Teraz o scanf
scanf podajesz parametry jako adresy kolejno wpisywanych liczb cz znaków i nie możesz do 1B zmiennej używać operatoa konwersji który zapisuje pobrane słowo w 2/4B.
%c - jest dla char i jeżeli chcesz jeden znak to właśnie go uryzwaj a parametr podajesz przez &zmienna.
Jeżeli wczytujesz ciąg znaków "string" to masz operator
%s - i wtedy jako parametr musisz podać nazwę tablicy a nazwa tablicy jest jej adrezem więc po prostu podajesz [code]zmienna[/code].
Kiedy urzywaz liczb to stosujesz operatory konwersji do liczb
%d,%i,%f.
Jeżeli masz zmienną typu unsigned tak jak ty tam to przed daną literą dajesz u
%uc,%ud nie ma uf a nie wiem jak jest z us.
Ale nie musiszz tego stosować jeżeli dasz c a będziesz miał typ uchar to ci samo skonwertuje.

0

scanf to bardzo niewdzięczna funkcja i radzę uduczyć ci się jej stosowania.
Jak jusz wcześniej pisali lepiej to wykonać an getch,getche.

Muszę używać o ile to możliwe funkcji ANSI C. Obydwie wymienione przez ciebie funkcje nie znajdują się w standardzie (co najwyżej getchar mógłbym próbować).

Po pierwszw dałeś na imię i nazwisko stały rozmiar pola a nie zabezpieczyłeś przed jego przekroczeniem i będziesz miał kłopoty jeżeli ktoś ma długie nazwisko np dwuczłonowe i przekroczy rozmiar pola i wejdzie ci na imię a potem imię zapiszesz i co może ci wyświetlić część nazwiska z imieniem.

Na szczęście to jest tylko program na laborki i akurat dane nie przekroczą zakresu :)

Druga żecz jest taka że musisz pamiętać o wielkościach danego typu i w zależności od kompilatora na jakim siądziesz sprawdzić sobie wielkość danych typów.

Rozmiary tych typów akurat znam. Ale nie zauważyłem, że scanf wczytuje przy %d jedynie int.

unsigned rózni się tym od signed że ostatni najstarszy bit tego słowa jest bitem znaku i tak dla czar signed -128do 127 a unsigned od 0 do 255. Standardowe znaki mieszczą się do 127 to więc do przechowywanie jakiś znaczkuw to jest twoja decyzja.

To są przyzwyczajenia z Delphi. Char/Byte oraz ShortInt :)
A ja akurat pozwalam na wprowadzanie polskich znaków diakrytycznych, więc te powyżej 127 przydają się mi :)

Kiedy urzywaz liczb to stosujesz operatory konwersji do liczb
%d,%i,%f.
Jeżeli masz zmienną typu unsigned tak jak ty tam to przed daną literą dajesz u
%uc,%ud nie ma uf a nie wiem jak jest z us.
Ale nie musiszz tego stosować jeżeli dasz c a będziesz miał typ uchar to ci samo skonwertuje.

Ale nie mogę użyć scanf bezpośrednio wpisując liczbę z przedziału 0..255. Muszę pośrednio przez int.

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