Frage von Alinchen24, 12

Welchen logischen Fehler mache ich beim überprüfen der Zahlen im struct in c?

hier mein code^^ laut compiler funktioniert er aber iwie macht er nicht das was er tun soll^^ danken für die hilfe schonmal :)

include

include

typedef struct {

char nachname[30];

float note;

} student;

int main(){

student *student1;

student1 = ( student * ) malloc (sizeof (student)) ;

printf("Geben Sie die Anzahl an stundenten an");

int size;

scanf("%i", &size);

int i;

for (i=0; i<size; i++){

//Studenten einlesen

printf("Geben Sie den nachnamen und die note ein\n");

student1[i].nachname[30] = scanf("%s", &student1-> nachname[30]);

student1[i].note = scanf("%fl", &student1 -> note);

//Gültigkeit der Note überprüfen

while(student1[i].note <= 1.0){

printf("Geben Sie eine GÜLTIGE note ein\n");

student1[i].note = scanf("%fl", &student1 -> note);

}

while(student1[i].note >= 5.0){

printf("Geben Sie eine GÜLTIGE note ein\n");

student1[i].note = scanf("%fl", &student1 -> note);

}

}

return 0;

}

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von PWolff, 12

In der Deklaration

char nachname[30];

bedeutet die [30] die Länge des Arrays, in

student1[i].nachname[30] = scanf("%s", &student1-> nachname[30]);

das Element des Arrays mit dem Index 30 (was übrigens genau 1 Stelle hinter dem Array liegt, da die Indizes bei 0 beginnen).

-----

Dann allozierst du den Speicher für 1 Struktur student, greifst aber danach auf indizierte Werte zurück, was im Fall 0 <= Anzahl <= 1 kein Problem darstellt, aber für i > 0 greifst du auf Speicher zu, der entweder überhaupt nicht oder für andere Variablen alloziert ist.

-----

Nun zu deiner eigentlichen Frage:

Vermutlich willst du die while-Schleife(n) so lange durchlaufen, bis eine gültige Note vorliegt. Überleg mal, wie viele Schleifen du maximal haben darfst, um zuverlässig immer wieder an den Anfang der Prüfung zurückkehren zu können (Unterschleifen sind erlaubt, aber ob sie sinnvoll sind, ist eine andere Frage.)

-----

Schau dir DRINGEND noch mal die Arbeitsweise von scanf an, insbesondere, wo der Variablenname steht und was der Rückgabewert ist.

Und stell sicher, dass man keine Namen länger als 30 Zeichen eingeben kann. Dass C hier und an ähnlichen Stellen keine eingebaute Prüfung hat, ist eine der Hauptursachen für Sicherheitslücken!

(ich bin mir nicht 100%ig sicher, was scanf im besonderen in Bezug auf buffer overruns betrifft, da bei C aber Geschwindigkeit und Einfachheit (der Compiler-Implementierung, nicht des Programmierens) eine weit höhere Priorität hat als Sicherheit, dürfte diese Gefahr auch hier bestehen.)

siehe z. B. http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/004_c_ein_ausgabe_001.htm

Kommentar von PWolff ,

Programmieranfängern C beizubringen sollte mit zehn Peitschenhieben sowie Bug- und Sicherheitslückensuche und -flicken im Code anderer Leute nicht unter zwei Jahren bestraft werden.

Kommentar von ceevee ,

Ich vermute (ich hoffe), dass Alinchen im Rahmen eines Studiums / einer Ausbildung momentan gezwungen ist, C zu lernen. Sie stellt ja schon seit ein paar Tagen fragen dazu. Ansonsten ist C als erste Programmiersprache Masochismus pur. :)

Antwort
von maximilianus7, 11

gibt er nicht mal ne warnung bei student1[i] ?

ich zweifel allmählich, ob C eine programmiersprache ist, oder nur ein witz.

Kommentar von Alinchen24 ,

nope^^

Kommentar von PWolff ,

C ist am ehesten so was wie ein Übergang zwischen Assembler und verständlicher Programmiersprache. Ein bisschen strukturierter, ansonsten mit fast allen Vor- und Nachteilen von Assembler.

Kommentar von DoTheBounce ,

Nein, warum sollte er auch? Student1 ist nix weiter als ein Pointer in ein vom User angefordertes Stück Speicher. student1[i] macht nichts weiter als diesen Pointer um i * sizeof(student) zu verschieben. Das Ergebnis ist wiederum ein Pointer auf irgendein anderes Stück Speicher (das der Nutzer nicht allokiert hat und in dem wasauchimmer steht). Im schlimmsten Fall könnte es einen SegFault bei der Ausführung geben

Antwort
von ceevee, 8

Es wäre noch schön zu wissen, was dein Programm fälschlicherweise macht. Was spontan falsch aussieht, ist deine while-Schleife, ich würde da eine Schleife nehmen (nicht zwei) und so beginnen lassen:

while(student1[i].note < 1.0 || student[i].note > 5.0) {

Keine passende Antwort gefunden?

Fragen Sie die Community