Array mit unbestimmter Größe erstellen
-
Apley schrieb:
Am Anfang steht " Gefordert ist eine Ansi C implementierte Funktion, deren Form so auszusehen hat...." . Als abgabe wird dann eine header mit cpp und main.cpp verlangt. Was soll ich machen?!
Dem Prof sagen, dass er hierherkommen soll um C zu lernen.
ten schrieb:
was mich mal echt geschockt hat, ist sowas:
char a[] = {1,2,3}; 3[a] = 10; // <-- kein syntax error!
ich weiss jetzt noch nicht mal in welcher sprache das ging, php glaub' ich...
a[3]
*(a + 3)
*(3 + a)
3[a]Dass er dabei an nicht-reservierten Speicher schreibt ignorieren wir mal
-
Erstens: Du hast zwei verschiedene Funktionen mit dem Namen w123456() (die im Hauptrpogramm erwartet einen char, die in der w123456.cpp ein char-Array). Unter C++ wäre das womöglich legal (Überladung - könnte höchstens vom Linker moniert werden), in C definitiv nicht.
Zweitens: Diese sizeof-Konstruktion funktioniert nur recht eingeschränkt - und in deinem Fall liefert sie nicht das richtige Ergebnis. Nimm lieber strlen(), um die Länge des übergebenen Strings zu bestimmen.
Drittens: Wo hast du die lokalen Variablen der w123456() definiert?
Viertens: Der Ausdruck
void abort(void);
ist kein Funktionsaufruf - an der Stelle brauchst du einabort();
Fünftens @Swordfish: Dies ist das ANSI C Board, da bringt es nichts, C++ spezifische Faktoren zu diskutieren (C-Header, void-Paramterlisten, int main(void), etc. - btw sind die auch in C++ legal zu verwenden).
@ten: Das geht sogar in C
Der []-Operator
p[i]
ist eine Kurzform für*(p+i)
- und der ist witzigerweise kommutativ.
-
TactX schrieb:
Dass er dabei an nicht-reservierten Speicher schreibt ignorieren wir mal
du siehst einfach alles
CStoll schrieb:
...und der ist witzigerweise kommutativ.
ja, komisch, ne?
-
Apley schrieb:
Am Anfang steht " Gefordert ist eine Ansi C implementierte Funktion, deren Form so auszusehen hat...." . Als abgabe wird dann eine header mit cpp und main.cpp verlangt.
Man kann natürlich so großzügig sein zu sagen dass ein C-Programm auch die Endung .q haben könnte, aber normalerweise wäre diese Aussage ausreichend, den Herrn Prof. Dr. Thomas Zielke von der Hochschule zu verweisen.
Was ich auch sehr lustig finde: Ihr sollt die Aufgabe ausschließlich auf einer CD-ROM abgeben? Hat dort jeder Student sein eigenes Presswerk?
(Auch wenn klar sein dürfte, dass CD-R gemeint ist: Selbst zu verlangen, dass jeder Student Windows und einen Brenner haben muss, finde ich schon arg).
-
Es werden Strings als Eingabe verlangt. Mit int wäre ich schon längst fertig
Dann lies doch einen vollständigen String ein und wandele ihn in ein Int um. Es gibt auch dazu eine Funktion, weis nur den Namen nicht mehr. Google ist dein Freund
Aber das ist der Alptraum:
for(int i = 0; i < numbers; i++) // Schleife für die Aufnahme der Ziffern { scanf("%s", &input[i]); }
Soll das eine Matrikelnummer sein? Da muss ich ja 8 mal Enter drücken. Ausserdem ist dann scanf("%s", &input[i]); eh falsch. %s liest einen String ein, keinen Char! Ein String ist mindestens 2 Zeichen. Strings sind Null-Terminiert.
Das wäre richtiger:c Single character: Reads the next character. If a width different from 1 is specified, the function reads width characters and stores them in the successive locations of the array passed as argument. No null character is appended at the end. char *
Einen String kannst du so einlesen:
char buffer[256]; scanf("%s", &buffer);
Und dann den buffer in einen integer umwandeln mit der passenden Funktion. Hier müsstest du sie finden: http://www.cplusplus.com/reference/clibrary/
switch (pruefziffer) // Printanweisung für die Prüfziffer { case 1: printf("1\n\n\n"); break; case 2: printf("2\n\n\n"); break; case 3: printf("3\n\n\n"); break; case 4: printf("4\n\n\n"); break; case 5: printf("5\n\n\n"); break; case 6: printf("6\n\n\n"); break; case 7: printf("7\n\n\n"); break; case 8: printf("8\n\n\n"); break; case 9: printf("9\n\n\n"); break; } }
Was soll der Schrott? Kannst du nicht einfach printf("%d\n", pruefziffer); verwenden?
Schon genannt, aber hier nochmal:
float w123456 (const char Martikelnr[]) // Der Funktionname muss so aussehen. Darf nicht verändert werden { n = sizeof(Martikelnr) / sizeof(char); // ^ n ist nicht definiert for (r = 0; r < n-1; r++) // prüfen der Martikelnr auf // ^ r ist nicht definiert Fehleingabe { if(Martikelnr[r] > d || Martikelnr[r] < e) /* es wird // ^ ^ d und e ist nicht definiert getestet ob das Zeichen nach ASCII über 9 oder unter 0 liegen */ return rueckwert_an_main = 2; // WTF ist das?? ein return 2; reicht! else if (Martikelnr[r] != EigeneMartikelnr[r]) return rueckwert_an_main = 1; /* Falsche // WTF ist das?? ein return 1; reicht! Martikelnummer */ else return rueckwert_an_main = 0; /* Richtige // WTF ist das?? ein return 0; reicht! Martikelnummer */ } }
Was hast du für einen Compiler? Der müsste es dir doch sagen: r is used but not defined. Oder sowas ähnliches.
PS: WTF = What the f*u*c*k
// Der Funktionname muss so aussehen. Darf nicht verändert werden
btw, muss der Name der Funktion so heißen oder muss der Funktionsprototyp so aussehen?
-
DEvent schrieb:
Es werden Strings als Eingabe verlangt. Mit int wäre ich schon längst fertig
Dann lies doch einen vollständigen String ein und wandele ihn in ein Int um. Es gibt auch dazu eine Funktion, weis nur den Namen nicht mehr. Google ist dein Freund
Da gibt's einige - atoi(), strtol(), sscanf() - such dir was aus
(oder schau mal in die C++ FAQ unter "Einmal Zahl und zurück")
-
for(int i = 0; i < numbers; i++) // Schleife für die Aufnahme der Ziffern { scanf("%s", &input[i]); }
Es ist mir bewusst das hier ein String eingelesen wird und dann zwei Zeichen abgespeichert werden. Aber als ich diese Schleife getest habe und auch die Ausgabe als Prüfung ausgegeben habe war alles so wie ich es mir wünschte.
Obwohl deine Lösung ist ja fast das selbe. Werde es testen un bei Erfolg einsetzen. Nichts gegen deine Lösung aber du kennst meine Unfähigkeit nichtJungs, ihr zerlegt mich ja richtig. Komm mir ja richtig unfähig vor
Und dabei war ich ja schon ganz Stolz das ich nur noch eine Fehlermeldung herausbekommen habe.
Das soll im Programm dann später so ausshen. Es war jetzt nur einfachheitshalber mit 1,2,3 geschrieben
switch (pruefziffer) // Printanweisung für die Prüfziffer { case 0: printf(" 0000000 \n"); printf(" 0 0 \n"); printf(" 0 0 \n"); printf(" 0 0 \n"); printf(" 0000000 \n\n"); break;
Dann mal nächste Baustelle. Vorhin hatte ich vergessen die header Datei zu posten
/*w123456.h*/ const char EigeneMartikelnr[]= { "123456" }; int i, r, n; char d = '9'; char e = '0'; float w123456(char);
und die dazugehörige cpp
/*w123456*/ #include "w123456.h" float w123456 (const char Martikelnr[]) { n = sizeof(Martikelnr) / sizeof(char); for (r = 0; r < n-1; r++) // prüfen der Martikelnr auf Fehleingabe { if(Martikelnr[r] > d || Martikelnr[r] < e) /* es wird getestet ob das Zeichen nach ASCII über 9 oder unter 0 liegen */ return = 2; else if (Martikelnr[r] != EigeneMartikelnr[r]) return = 1; /* Falsche Martikelnummer */ else return = 0; /* Richtige Martikelnummer */ } }
// Der Funktionname muss so aussehen. Darf nicht verändert werden
btw, muss der Name der Funktion so heißen oder muss der Funktionsprototyp so aussehen?liegt da irgendwo ein Unterschied? Da wird es bestimmt einen geben denn sonst hättest du bestimmt nachgefragt.
Also es ist eine ANSI C implementierte Funktion gefordert, deren Protoryp folgende Form haben mussfloat w123456 (const char *martikelnummer)
Desweiteren -> martikelnummer: als ersten Parameter erwartet die Funktion eine Zeichenkette (String), d.h einen Zeiger auf ein Feld vom Typ char.
Erst jetzt merke ich das er da einen Zeiger braucht. Ufffff... Ich kann denn Zeiger dann in meine header.cpp gar nicht mehr verarbeiten. muss ja alles umstellen.
Ich schmeiss das Ding in Tonne....
CStoll schrieb:
DEvent schrieb:
Es werden Strings als Eingabe verlangt. Mit int wäre ich schon längst fertig
Dann lies doch einen vollständigen String ein und wandele ihn in ein Int um. Es gibt auch dazu eine Funktion, weis nur den Namen nicht mehr. Google ist dein Freund
Da gibt's einige - atoi(), strtol(), sscanf() - such dir was aus
(oder schau mal in die C++ FAQ unter "Einmal Zahl und zurück")Ich hab mich gestern den ganzen Tag nur mit diesen 3 Befehlen beschäftigt. Die Beispiel funktionierten alle, wollte ich das bei mir umsetzten ging nichts mehr. Ständig nur Fehlermeldungen. Deshalb auch meine fast resignation dem gegenüber.Hatte ich es schon erwähnt das ich es mir dann relativ einfach machen wollte. Werde es aber heute nochmal probieren.
Apley
-
Apley schrieb:
Jungs, ihr zerlegt mich ja richtig. Komm mir ja richtig unfähig vor
Und dabei war ich ja schon ganz Stolz das ich nur noch eine Fehlermeldung herausbekommen habe.
Selbst eine Fehlermeldung ist eine zu viel
(und idR sind die Fehler, die der Compiler nicht entdeckt, die unangenehmeren).
Dann mal nächste Baustelle. Vorhin hatte ich vergessen die header Datei zu posten
/*w123456.h*/ const char EigeneMartikelnr[]= { "123456" }; int i, r, n; char d = '9'; char e = '0'; float w123456(char);
Diese Variablen haben nichts im Header zu suchen, die werden nur lokal in deiner Funktion benötigt, also mußt du sie auch nur dort anlegen. Und wenn in der Aufgabe steht, daß die Funktion den Prototyp
float w123456(const char* matrikelnummer);
haben soll, ist die obige Deklaration auch falsch (die Array-Version in der .CPP kann man noch durchgehen lassen, die ist semantisch äquivalent zu der geforderten Pointer-Version).Desweiteren -> martikelnummer: als ersten Parameter erwartet die Funktion eine Zeichenkette (String), d.h einen Zeiger auf ein Feld vom Typ char.
Erst jetzt merke ich das er da einen Zeiger braucht. Ufffff... Ich kann denn Zeiger dann in meine header.cpp gar nicht mehr verarbeiten. muss ja alles umstellen.
Ich schmeiss das Ding in Tonne....
So tragisch ist das auch wieder nicht - bei einem ordentlichen String kannst du mit strlen() die länge herausfinden (im Gegensatz zu deinem sizeof()-Ansatz funktioniert das sogar ;)). Und außerdem solltest du dir mal die Funktionen isdigit() und strcmp() ansehen.
PS: Übrigens werden C-Programme gewöhnlich als "xxx.c" gespeichert - die Endung .cpp deutet auf C++ Programme hin.
-
CStoll schrieb:
Und wenn in der Aufgabe steht, daß die Funktion den Prototyp
float w123456(const char* matrikelnummer);
haben soll, ist die obige Deklaration auch falsch (die Array-Version in der .CPP kann man noch durchgehen lassen, die ist semantisch äquivalent zu der geforderten Pointer-Version).Wie würde es dann denn richtig heißen oder aussehen?
Was kommt dann noch in die header datei denn rein? Einfach nur eine Weiterleitung zur richtigen Funktion? Über Headerdateien habe ich leider nicht viele Infos gefunden, so dass ich mich eher an das Skript gehalten hab.
Zur Dateieindung cpp sag ich nichts mehr. gefordert ist C aber zu speichern in cpp. Frag jetzt nicht nach dem wieso.
werde dann mal meinen code ändern und schauen was passiert.
Nur das mit dem Zeiger macht mir etwas schwierigkeiten. Denn ich weiß nicht wieso er da einen Zeiger haben will. Ich weiß mit zeigern so gut wie gar nicht umzugehen. Muss mal sehen wie ich das da löse.
nur zum Verständniss: Die funktion erwartet da einen Zeiger der auch ein Char zeigt, bei mir also der input-String
char *martikelnr; char input = {"123456"}; martikelnr = &input;
und dies Martikelnr wird dann die funktion übergeben
. . w123456 (Martikelnr); . .
sehe ich das so richtig?
Apley
-
Apley schrieb:
nur zum Verständniss: Die funktion erwartet da einen Zeiger der auch ein Char zeigt, bei mir also der input-String
Die Funktion erwartet einen Zeiger, der auf eine Reihe von chars zeigt. Und da liegt auch der Knackpunkt: Ein Char ist immer nur ein Zeichen. Um eine Kette von Zeichen zu übergeben, nutzt Du einen Zeiger auf das erste dieser Zeichen. Wobei ein Array grundsätzlich als Zeiger benutzt werden kann.
Damit ist dieser Teil schonmal hinfällig:
char input = {"123456"};
Ein char ist ein Zeichen, eins eins eins ;). Richtig wäre:
char input[] = "123456";
Dieses Array namens input darfst Du allerdings als Zeiger verwenden, also auch ohne Adressoperator an die Funktion übergeben.
w123456(input); /* gleichbedeutend: */ char* matrikelnr = input; w123456(matrikelnr);
BTW: Wieso nutzt Du immer [ cs]-Tags? C-Quellcode mit C++-Dateiendung und C#-Syntaxhighlighting?
-
LordJaxom schrieb:
Damit ist dieser Teil schonmal hinfällig:
char input = {"123456"};
Ein char ist ein Zeichen, eins eins eins ;). Richtig wäre:
char input[] = "123456";
habe mich da vertippt. Ich meinte auch input [].
LordJaxom schrieb:
BTW: Wieso nutzt Du immer [ cs]-Tags? C-Quellcode mit C++-Dateiendung und C#-Syntaxhighlighting?
Ist das nicht eine schöne Kombination?
Ich hab erste jetzt gesehen das es auch [ cpp] tags gibt. War eher Unwissenheit.
So ich muss jetzt mal weg, mal sehen was ich heute Abend schaffe.
Apley
-
Apley schrieb:
CStoll schrieb:
Und wenn in der Aufgabe steht, daß die Funktion den Prototyp
float w123456(const char* matrikelnummer);
haben soll, ist die obige Deklaration auch falsch (die Array-Version in der .CPP kann man noch durchgehen lassen, die ist semantisch äquivalent zu der geforderten Pointer-Version).Wie würde es dann denn richtig heißen oder aussehen?
So wie es in der Aufgabenstellung steht. (die Variablen kannst du IN der Funktion deklarieren)
Was kommt dann noch in die header datei denn rein? Einfach nur eine Weiterleitung zur richtigen Funktion? Über Headerdateien habe ich leider nicht viele Infos gefunden, so dass ich mich eher an das Skript gehalten hab.
In die Headerdatei schreibst du nur die Deklarationen, die vom Hauptprogramm benötigt werden, also letztlich nur den Prototyp der Funktion w123456().
-
Wie kann ich denn jetzt den String input an die Funktion übergeben?
char input[]={(1,2,3)}
habe erst mal folgendes definiert
char input[]={(1,2,3)} // und dann so integriert if(w123456(input) == 0.0) //Hier meldet er mir immer noch fehler richtigeMartikelnr(); // ----------- so sieht der Funktionsname aus float w123456 (const char *Martikelnr)
Der Fehler lautet: cannot convert parameter 1 from 'char [256]' to 'char'
also wir kann ich das input array an die funktion ohne Fehler übergeben. Ich bekomm das nicht hin. Wüsste jetzt auch nicht woran es liegt, denn nach meiner Auffassung habe ich alles richtig geschrieben.
Apley
-
Apley schrieb:
char input[]={(1,2,3)}
das ist ein array mit nur einem element (der 3). lass die inneren klammern wech.
Apley schrieb:
Der Fehler lautet: cannot convert parameter 1 from 'char [256]' to 'char'
die funktion will offensichtlich nur ein einzelnes zeichen haben (char).
wenn sie eine zeichenkette verarbeiten soll, muss du sie 'f(char* s)' oder 'f(char s[])' nennen.btw: guck' dir nochmal ein c-tutorial an, z.b. das: http://gd.tuwien.ac.at/languages/c/programming-bbrown/
-
ten schrieb:
die funktion will offensichtlich nur ein einzelnes zeichen haben (char).
wenn sie eine zeichenkette verarbeiten soll, muss du sie 'f(char* s)' oder 'f(char s[])' nennen.Das hat jetzt super funktioniert. Nur wegen einem verrutschtem Sternchen tz tz
Nach dem Kompilieren bekomm ich keinen Fehler, jedoch wenn ich ausführen möchte bekomme ich folgende Fehlermeldung:
error LNK2019: unresolved external symbol "float __cdecl z497628(char *)" (?z497628@@YAMPAD@Z) referenced in function _main
C:\Dokumente und Einstellungen\Administrator\Eigene Dateien\Visual Studio 2005\Projects\Prüfziffernberechnung\Debug\Prüfziffernberechnung.exe : fatal error LNK1120: 1 unresolved externals
Kann jemand damit was anfangen?
EDIT: Hat sich erledigt. Habs rausgefunden. Das Programm läuft jetzt fast einwandfrei. YUHU
Danke an alle die so viel Geduld mit mir aufgebracht haben, besonders ten und DEvent, und mich sehr tatkräftig unterstützt haben. Ohne euch hätte ich es bestimmt nie so schnell geschafft.
Apley
-
Du musst das Sourcefile in dem die z497628 zusammen mit dem Hauptprogramm linken, sprich das File ins Projekt aufnehmen.
-
EDIT: Hat sich erledigt. Habs rausgefunden. Das Programm läuft jetzt fast einwandfrei. YUHU
War ja eine schwere Geburt. Fast alle Fehler hättest du vermeiden können, wenn du dich mit der Sprache C beschäftigt hättest. Der Prof ist auch nicht der hellste in Sachen C, oder? .cpp Dateien für C-Sprache, char* für eine Matrikelnummer, obwohl eine Matrikelnummer eine Nummer, also eine Zahl ist.
Sagmal, ist matrikelnummer, der du der Funktion
float w123456(const char* matrikelnummer);
übergibst, überhaupt Null-Terminiert? Sonst funktioniert nämlich strlen() nicht! Denn wie soll man den feststellen, wann die Zahlenfolge in matrikelnummer endet?Das hat früher funktioniert, weil matrikelnummer ein Array war und der Compiler es automatisch abspeichert, wieviel Elemente ein Array hat. Das kann der Compiler bei Pointern nicht machen!
-
der Funktion
float w123456(const char* matrikelnummer);übergebe ich den Eingabe-String input. also da sollte soweit alles gut gehen. Wenn wir schon dabei sind, es meldet mir trotzdem noch Warnungen.
const char EigeneMartikelnr[]= { "123456" }; float w123456 (const char* Martikelnr) { int r, n; char d = '9'; char e = '0'; n = strlen(Martikelnr); // WARNUNG: warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data for (r = 0; r < n; r++) // prüfen der Martikelnr auf Fehleingabe { if(strcmp(EigeneMartikelnr,Martikelnr)==0) return 0; // Richtige Martikelnummer else if (Martikelnr[r] > d || Martikelnr[r] < e) // es wird getestet ob das Zeichen nach ASCII über 9 oder unter 0 liegen return 2; else if (Martikelnr[r] != EigeneMartikelnr[r]) return 1; // Falsche Martikelnummer } }
und die zweite: warning C4715: 'w123456' : not all control paths return a value
Wieso durchläuft er meine schleife nicht durch? Irgendwo ist der wurm drin.
PS: Also ich bin auch nicht gerade begeistert vom Prof., aber was will man machen, es gibt überall Leute die man nicht mag und trotzdem mit denen auskommen muss. Früher soll ja ganz in Ordnung gewesen sein.
Schon an der Aufgabe bin ich fast gescheitert. Sie war mir fast zu kompliziert gestellt. Alles was ich an der Aufgabe nicht verstanden hab, habe ich ausgelassen. Bei Interesse kann man es sich mal durchlesen. Ist irgendwo auf den letzten Seiten.:)Apley
-
das 'strcmp' gehört vor die schleife und damit entfällt auch der zeichenweise test auf ungleich am ende der schleife.
und die zweite: warning C4715: 'w123456' : not all control paths return a value
was passiert, wenn in der schleife kein test positiv ausfällt?
btw: nimm's mir bitte nicht übel, aber du solltest dir dringend nochmal die C grundlagen aneignen, ohne diese elementaren kenntnisse ist so ein (relativ einfaches) programm 3 nummern zu gross für dich...
-
// Überprüfen ob Martikelnr nur Zahlen enthält for ( int i = 0; i < n; i++ ) { if ( isdigit(Martikelnr[i]) == 0 ) return 1; // Enthält nicht nur Zahlen } // Überprüfen ob EigeneMartikelnr, Martikelnr gleich sind if ( strcmp(EigeneMartikelnr, Martikelnr) == 0 ) return 0; // EigeneMartikelnr, Martikelnr sind ungleich return 1;