Array of structure
-
Wieso gibt es denn für ExamID eigentlich nur 3, bzw. mit Stringende vier Zeichen? Hier setze ich doch wie bei Matr auch 6+1 Zeichen fest.
Und wie kann ich die Eingabe begrenzen?
-
Tergo schrieb:
Edit: Verstehe auch einfach nicht, wieso >= 0.7 nicht funktioniert.

Nicht alle Fließkommazahlen können exakt abgespeichert werden.
Oft ist es ein Nähreungswert.Dein mark ist vom Typ
float, der ist nicht so genau wie eine Zahl vom Typdouble.
Die 0.7 werden aber als double aufgefasst. Beim Vergleich wird das ungenaue mark in eindoublegewandelt und dann mit dem genauen 0.7 verglichen.Ist wie bei 1/3 bei Dezimalzahlen: 0,333 < 0,3333333
(Intern arbeitet der Rechner mit Binärdarstellung)Du kannst dem Compiler aber sagen, dass er die 0,7 als
floatauffassen soll. Setze ein f dahinter: 0.7f
-
Tergo schrieb:
Wieso gibt es denn für ExamID eigentlich nur 3, bzw. mit Stringende vier Zeichen? Hier setze ich doch wie bei Matr auch 6+1 Zeichen fest.
Du musst ja nicht 6 Zeichen eingeben, 3 reichen doch auch.
Tergo schrieb:
Und wie kann ich die Eingabe begrenzen?
Das machst du doch schon.
Aber mit dem falschen Wert.
-
f habe ich nun dahinter gesetzt. Es funktioniert

Laut Aufgabe soll die ExamID aber 6 Stellen haben

Das heißt, ich wäre doch dann mit 6+1 bei ExamID und Matr gut bedient oder?
-
Tergo hat jetzt in Dirk einen C-Privatlehrer gefunden.

Btw, bitte nicht falsch verstehen, Dirk. Ich finde es gut, wie du das machst.
Schon mal daran gedacht, daraus einen Beruf zu machen?
-
Das ist die letzte Information, die ich benötige, dann wäre das Programm fertig

Bin Dirk, und natürlich auch dir, Andromeda, auch wahnsinnig dankbar für die Hilfe

-
Irgenwann hast du angefangen im Formatsring von
scanfeine Ziffer (7) einzubauen.
Wieso, weshalb, warum?
-
Ich dachte das wäre dafür, um die Eingabe zu begrenzen

Oder muss hier eine 6 stehen?
-
Tergo schrieb:
Ich dachte das wäre dafür, um die Eingabe zu begrenzen

Oder muss hier eine 6 stehen?
Du willst einen String mit 6 Zeichen.
Ein String in C hat aber üblicherweise n+1 Zeichen, wegen der abschließenden 0.
Was sagt uns das?
-
Dass ich 7 Zeichen brauche. Aber das habe ich doch, oder nicht?

Edit: ich poste hier nochmal den aktuellen Stand:
#include <stdio.h> #include <stdlib.h> #define MAXMATRNUM 6 #define MAXEXAMIDNUM 6 struct exam { char Matr[MAXMATRNUM+1]; char ExamID[MAXEXAMIDNUM+1]; float mark; }; int main() { int n,i,num=0; printf("Please enter the number of exams:\n"); scanf("%d", &n); struct exam *database; database = malloc (n * sizeof(struct exam)); if (database == 0) return EXIT_FAILURE; for(i=0; i<n; i++) { printf("Please enter the Matriculation Number %d\n",i+1); scanf("%7s",&*database[i].Matr); printf("Please enter the Exam-ID %d\n",i+1); scanf("%7s",&*database[i].ExamID); printf("Please enter the Mark %d\n",i+1); scanf("%f",&database[i].mark); } for(i=0; i<n; i++) { if(database[i].mark>=0.7f && database[i].mark<=4.0) { num++; } } printf("The number of passed exams is: %d\n", num); free (database); return EXIT_SUCCESS; }
-
Tergo schrieb:
Dass ich 7 Zeichen brauche. Aber das habe ich doch, oder nicht?

Du sollest dir daher darüber klar werden, was "%7s" im scanf-Kontext bedeutet.
Also RTFSM!
-
Also scanf speichert die Werte, die eingegeben werden unter der Adresse von *database[i]. Wenn nun %7s angegeben wird, werden nur die ersten 7 Zeichen gespeichert, richtig? Das heißt, wenn ich 012345 eingebe, werden diese gespeichert inklusive des String-Endes '0'.
-
Tergo schrieb:
Wenn nun %7s angegeben wird, werden nur die ersten 7 Zeichen gespeichert, richtig? Das heißt, wenn ich 012345 eingebe, werden diese gespeichert inklusive des String-Endes '0'.
"012345" sind aber 6 Zeichen.
Preisfrage: wie viele Zeichen, inklusive der infamen 0, werden bei %7s gespeicher?
[] 6 Zeichen?
[] 7 Zeichen?
[] 8 Zeichen?Nur eine Antwort ist richtig.
-
Tergo schrieb:
Ich dachte das wäre dafür, um die Eingabe zu begrenzen

Ja, ja das ist es.
Tergo schrieb:
Oder muss hier eine 6 stehen?
scanf schrieb:
%[*][width][length]specifier
width Specifies the maximum number of characters to be read in the current reading operation (optional).
Tergo schrieb:
Also scanf speichert die Werte, die eingegeben werden unter der Adresse von *database[i]. Wenn nun %7s angegeben wird, werden nur die ersten 7 Zeichen gespeichert, richtig? Das heißt, wenn ich 012345 eingebe, werden diese gespeichert inklusive des String-Endes '0'.
012345 sind nur 6 Zeichen. Du erlaubst aber 7 Zeichen: 1234567. Und dann kommt noch automatisch die '\0'. Was dann 8 Zeichen wären. Dein Array hat aber nur Platz für 7 Zeichen.
(Du kannst aber auch Buchstaben eingeben)
-
Das heißt es müsste einfach 6s sein? Ich dachte, man müsste die '0' am Stringende selber mit einberechnen.
#include <stdio.h> #include <stdlib.h> #define MAXMATRNUM 6 #define MAXEXAMIDNUM 6 struct exam { char Matr[MAXMATRNUM+1]; char ExamID[MAXEXAMIDNUM+1]; float mark; }; int main() { int n,i,num=0; printf("Please enter the number of exams:\n"); scanf("%d", &n); struct exam *database; database = malloc (n * sizeof(struct exam)); if (database == 0) return EXIT_FAILURE; for(i=0; i<n; i++) { printf("Please enter the Matriculation Number %d\n",i+1); scanf("%6s",&*database[i].Matr); printf("Please enter the Exam-ID %d\n",i+1); scanf("%6s",&*database[i].ExamID); printf("Please enter the Mark %d\n",i+1); scanf("%f",&database[i].mark); } for(i=0; i<n; i++) { if(database[i].mark>=0.7f && database[i].mark<=4.0) { num++; } } printf("The number of passed exams is: %d\n", num); free (database); return EXIT_SUCCESS; }So dann?
-
Tergo schrieb:
Ich dachte, man müsste die '0' am Stringende selber mit einberechnen.
Das tust du ja. Siehe die "+1" in der Struct-Definition.
-
Okay, das leuchtet mir ein

Das heißt, das Programm ist nun fertig?
-
Tergo schrieb:
Okay, das leuchtet mir ein

Das heißt, das Programm ist nun fertig?Es ist niemals fertig.

Btw, um die Beziehungen zwischen Arraygröße, gewünschter Zeichenzahl und scanf-Formatstring herzustellen, beachte bitte folgenden Beispielcode:
#include <stdio.h> // So viele Zeichen sind gewüscht #define STRLEN 6 // + abschließender 0 #define RAW_STRLEN (STRLEN+1) // Format String für scanf bauen #define STR_EXPAND(tok) #tok #define STR(tok) STR_EXPAND(tok) #define S_FORMAT "%"STR(STRLEN)"s" // Test int main() { char str[RAW_STRLEN]; scanf (S_FORMAT, str); printf ("%s", str); }
-
Danke für den Hinweis
Jetzt habe ich es verstanden.Aber soweit scheint die Aufgabe nun gelöst, oder?

-
Tergo schrieb:
Aber soweit scheint die Aufgabe nun gelöst, oder?

Naja, bei einem wohlwollenden Prof ist jetzt zumindest ein "Ausreichend" drin.
Fairerweise solltest du aber Dirk aus dem C-Forum erwähnen, ohne den du die Aufgabe niemals geschafft hättest.