struktury i wskaźniki

0

Witam!
Taki kod najpierw zarzucę:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
void pobierz_dane(struct dane *wsk);

struct wyniki_badan {
		int cisnienie;
		int masa;
};	

struct dane {
		char *imie_nazw;
		long int  PESEL;
		struct wyniki_badan wyn;
};




int main(void) {
	int i;	
	int ln;

	
	struct dane osoba[4];
	
	/*dane wczytywać w funkcji dla każego oddzielnie - funkcja wczytuje dane jednego pacj */
	
	for (i=0; i<4; i++) {
		pobierz_dane(&osoba[i]);
	}
	
	printf("\n======================================\n");
	printf("%s", osoba[i].imie_nazw);
	for (i=0; i<4; i++) {
		printf("Imie i nazwisko pacjenta %d: %s\n", i+1, osoba[i].imie_nazw);
		printf("Pesel: %d\n", osoba[i].PESEL);
		printf("Masa: %d\n", osoba[i].wyn.masa);
		printf("Cisnienie: %d\n", osoba[i].wyn.cisnienie);
		printf("\n\n");
	}
	

	scanf("%d", &ln);
	return 0;
}

void pobierz_dane(struct dane *wsk) {
	char temp[81];
	int rozmiar;
	int licznik = 0;
	char pesel[11];
	char cisnienie[5];
	char masa[5];

	puts("Podaj imie i nazwisko: ");
	gets(temp);

	
	
	wsk->imie_nazw = (char*)malloc(strlen(temp) * sizeof(char));
	strcpy(wsk->imie_nazw, temp);
	

	puts("PESEL: ");
	gets(pesel);
	
	wsk->PESEL = atoi(pesel);

	puts("Cisnienie: ");
	gets(cisnienie);

	wsk->wyn.cisnienie = atoi(cisnienie);

	puts("Masa: ");
	gets(masa);

	wsk->wyn.masa = atoi(masa);
} 

Program ma pobierać dane 4rech osób. Jednak coś nie tak mam przy wskaźniku na char *imie_nazw, który jest w strukturze. Jako, że się dopiero uczę liczę na Waszą pomoc. Kompilator wywala błąd podczas próby wyświetlenia, coś w deseń: "Access violation reading location". W debugerze znalazłem informacje "bad ptr". Pytanie, jak poprawnie się dobrać wskaźnikiem do tego elementu?
Z góry dzięki za pomoc ;)

0
        wsk->imie_nazw = (char*)malloc(strlen(temp) * sizeof(char));
wsk->imie_nazw = (char*)malloc(strlen(temp)+1);

potrzeba jednego więcej bajtu na kończący znak \0.
ponadto sizeof(char) jest zdefiniowany w standardzie jako zawsze równy 1.

możesz też dać na sztywno rozmiar c-stringa

struct dane {
                char imie_nazw[256]; // max 255 znaków + '\0'
                long int  PESEL;
                struct wyniki_badan wyn;
};

i wtedy bez malloc. w ten sposób nie musisz potem pamiętać o free.

0

Zapomniałem napisać, że musi być malloc - takie założenie.
Zmieniłem wiersz z malloc na taki jaki mi napisałeś. Dorzuciłem jeszcze free o którym zapomniałem. I dalej nie działa, więc gdzie jest jeszcze źle?

0

przenieś prototyp void pobierz_dane poniżej struct wyniki_badan i struct dane

0

Zrobione, ale bez większych zmian. Dalej błąd podczas wyświetlania.

0
einTier13 napisał(a)

Zrobione, ale bez większych zmian. Dalej błąd podczas wyświetlania.

Może:

wsk->imie_nazw = (char*)malloc(((strlen(temp) + 1) * sizeof(char));
Azarien napisał(a)

ponadto sizeof(char) jest zdefiniowany w standardzie jako zawsze równy 1.

To w C++. W C o ile się nie mylę char ma rozmiar równy typowi int i zwykle wynosi on 4 bajty. Możemy w C np. do typu char zapisać coś takiego:

char a = 'ABCD';

takie przypisanie jest ok i kompilator nie zgłosi błędu, ale tak naprawdę zapisze się tylko ta ostatnia litera.

0
wsk->imie_nazw = (char*)malloc((strlen(temp) + 1) * sizeof(char);

Co to ma robić? Chyba zapomniałeś o jeszcze jednym nawiasie:

wsk->imie_nazw = (char*)malloc(((strlen(temp) +1) * sizeof(char));

Oczywiście, nie jest zawsze równy 1. Wszystko zależy, dlatego daje się operator sizeof().

char a = 'ABCD'; == char a = 'D'; == char a = ('A', 'B', 'C', 'D');
0

Dalej mi nie działa - ten sam błąd. Co będzie źle w dalszym ciągu?

0
printf("%s", osoba[i].imie_nazw);

Skąd to wziąłeś? Od razu się na tym wywali. Masz już jedno takie w pętli, i tam ma być.

Pesel ma 11 cyfr, więc tablica znaków do wczytania powinna mieć długość przynajmniej 12 (przy wczytywaniu musisz zawsze zmieścić dodatkowy znak \0). W dodatku przy konwersji atoi, 11 cyfr nie zmieści się w int. Wygodniej byłoby przetrzymywać pesel w 11-elementowej tablicy znaków, zamiast zamieniać na liczbę.

Deklarację pobierz_dane powinieneś przenieść poniżej definicji struktury dane, albo strukturę zadeklarować wyżej.

Zamiast wczytywać ciśnienie i masę jako ciągi znaków, możesz przecież od razu użyć scanf("%d", &wsk->wyn.masa) (oczywiście z walidacją). To samo z ciśnieniem. Ponadto używanie gets jest niebezpieczne (możesz wylecieć poza tablicę, lepiej użyć fgets z ograniczeniem ilości znaków).

0

Oczywiście, nie jest zawsze równy 1. Wszystko zależy, dlatego daje się operator sizeof().

akurat przy char to nie zależy. zarówno w C jak i C++ sizeof(char) wynosi na pewno 1.

różnica jest przy sizeof('a'): w C++ zwróci sizeof(char), w C zwróci sizeof(int).

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