Länge eines Arrays begrenzen?
-
Du kannst auch einfach, falls du das Original nicht mehr brauchst, die terminierend Null nur verschieben, indem du sowas machst:
ent->d_name[strlen(ent->d_name)-6] = 0
-
MFK schrieb:
...
Saul, du musst hinter den gekürzten Text noch eine Nullterminierung anhängen. Nur so wissen die String- und Ausgabefunktionen, wo der String aufhört.Jo genau daran haben ich gedacht und das meinte ich mit meiner Aussage "Dummerweise behält er die restlichen Felder noch bei und setzt sie nicht "leer"."
Ich weiß halt nur nicht, wie ich das umsetzen muss.So?
cArray[0] = '0';
Das geht sicher nicht oder? Damit setze ich sicher nur das Zeichen bzw. den String auf 0. Dann würde die länge doch genau so lang sein, nur das der String mit Nullen aufgefüllt wurde (z.B. string00000000).
Genmutant schrieb:
Du kannst auch einfach, falls du das Original nicht mehr brauchst, die terminierend Null nur verschieben, indem du sowas machst:
ent->d_name[strlen(ent->d_name)-6] = 0
Ja genau sowas habe ich gebraucht. Danke Genmutant!!
Gruß Saul
p.s. die Lösung für MFK Ansatz, würde ich trotzdem gerne noch wissen.
-
Saul schrieb:
MFK schrieb:
...
Saul, du musst hinter den gekürzten Text noch eine Nullterminierung anhängen. Nur so wissen die String- und Ausgabefunktionen, wo der String aufhört.Jo genau daran haben ich gedacht und das meinte ich mit meiner Aussage "Dummerweise behält er die restlichen Felder noch bei und setzt sie nicht "leer"."
das geht auch nicht, da es keinen "leeren" Zustand, den du zuweisen kannst. Ein Bit kann 0 oder 1 sein, aber nicht "leer". Ein Array, welches du nicht über malloc/realloc/calloc angefordert hast, wirst du nicht vergrößern/verkleinern können. Das einzige, was du im Falle von Strings machen kannst, ist die \0-Terminierung früher zu setzen.
Saul schrieb:
So?
cArray[0] = '0';
damit weist du das 0-Zeichen (Ascii 48) zu, und nicht das \0-Terminierungszeichen \0 (Ascii 0)
cArray[0] = '\0';
aber das geht nur bei Strings, bzw. wenn du \0 als Terminierungszeichen hast. Hättest du ein Array von beliebigen 8-bit-breite Wörtern, die auf 0 sein können, dann musst du die Länge in einer anderen Variable mitführen.
-
supertux schrieb:
cArray[0] = '\0';
Wieso immer so verquast?
cArray[0] = 0;
Warum's den \0 Escape überhaupt gibt, weiß ich sowieso nicht.
-
Ok, dann hat sich das schonmal erledigt. Danke euch für eure Hilfe
Nun bin ich aber auf ein weiteres Problem gestoßen ...
Mein eigentliches Problem ist nämlich, das ich Bilder aus einem Ordner automatisch finden bzw. öffnen und dann verarbeiten möchte.
Bisher wollte ich es so lösen:int main(int argc, char** argv) { struct dirent *ent; DIR *dir; dir = opendir("../Ordner"); if (dir != NULL) { while ((ent = readdir (dir)) != NULL) { char dateien[]="temp"; memcpy(dateien, ent->d_name, sizeof(ent->d_name)); dateien[strlen(ent->d_name)-4] = 0; if (strlen(dateien)>2) { //const char* dateien= "Bild1"; char inputpath[300] = {0}; sprintf(inputpath, "../Ordner/%s.JPG", dateien); IplImage* img = cvLoadImage(inputpath, 1); ...
Es soll also per opendir, readdir und closedir der Ordner nach Bildern durchsucht und nur auf den Namen begrenzt werden (z.B. Bild1.jpg -> Bild1, Bild2.jpg -> Bild2), was ich nun durch Genmutants Hilfe soweit geklärt habe ... denke ich zumindest.
Diese Sollen dann nach und nach, jedes für sich geöffnet und dann später bearbeitet werden. Doch irgendetwas läuft bei der weitergabe der Bildnamen zum öffnen falsch.Die If-Schleife soll dazu dienen nur die Namen in dem Ordner und nicht die "Pünktchen" weiterzugeben, denn normaler Weise sieht die Ausgabe von readdir so aus:
.
..
Bild1.jpg
Bild2.jpgusw.
So und dann sollen die Namen mit dem Pfad verknüpft werden, damit die Bilder geöffnet werden können. Wenn ich das automatische auslesen mal weglasse und den Namen fest vorgebe, wie z.B. in meinem Kommentar //const char* dateien= "Bild1";
dann klappt alles wunderbar.
Hat jemand eine Idee, woran das liegen könnte?
Gruß Saul
-
Dein char-Array dateien ist dadurch, dass du es mit einem 4 Zeichen langen Literal initialisierst, genau 5 chars groß. Wenn du dann etwas größeres hineinkopierst, geht das in die Hose.
-
D.h. also wenn ich den Array dynamisch deklariere, so wie von Janjan und supertux beschrieben, müsste es klappen?
Das müsste dann so aussehen?
dateien = (charmalloc(strlen(ent->d_name)-4);
-
Den Rückgabewert von malloc soll man nicht casten. Und bedenke, dass du ein zusätzliches Byte für die Stringendemarkierung brauchst.
-
Also ich habs nochmal fix getestet ... Du hast recht MFK
Die Namen der Bilder in dem Ordner waren länger als z.B. Bild1, Bild2.
Wenn ich also das char-Array dateien nicht also "temp", sondern als "temporäredatei" deklariere funktioniert es.
Also ist die beste Möglichkeit ein dynamisches Array zu erstellen.MFK schrieb:
Den Rückgabewert von malloc soll man nicht casten. Und bedenke, dass du ein zusätzliches Byte für die Stringendemarkierung brauchst.
Meinst du so?
char *dateien = malloc(strlen(ent->d_name)-4);
dateien [strlen(ent->d_name)-5] = '\0';und zum schluss free(dateien);
-
Saul schrieb:
Meinst du so?
char *dateien = malloc(strlen(ent->d_name)-4);Nein.
Wenn du strlen-4 Zeichen reinkopieren willst, musst du für (strlen-4)+1 = strlen-3 Zeichen Speicher reservieren.Saul schrieb:
dateien [strlen(ent->d_name)-5] = '\0';
Du musst nur mehr Speicher reservieren. Die Endmarkierung war schon an der richtigen Stelle.
Auch wenn ich nicht verstehe, warum du die Endung erst abschneidest und dann wieder dranhängst.
-
Also irgendwie raff ich das nicht
Habs jetzt so geschriebenchar *dateien = malloc(strlen(ent->d_name)-3);
Dann kommt ein Initialisierungs-Fehler: 'void *' kann nicht in 'char *' konvertiert werden und somit übersetzt er das Prog nicht.
Wenn ich aber auf (charcaste dann übersetzt er zwar, aber gibt dann ein Debug-Fehler aus: Invalid allocation size.
MFK schrieb:
...
Auch wenn ich nicht verstehe, warum du die Endung erst abschneidest und dann wieder dranhängst.Das ist dazu gedacht, um den Bildnamen weitere Daten von dem bearbeiteten Bild zu übergeben und dann wieder zusammen zu setzen,
z.B. Breite und Höhe -> Bild1 (800*600).jpg
Gruß Saul
-
Saul schrieb:
Also irgendwie raff ich das nicht
Habs jetzt so geschriebenchar *dateien = malloc(strlen(ent->d_name)-3);
Dann kommt ein Initialisierungs-Fehler: 'void *' kann nicht in 'char *' konvertiert werden und somit übersetzt er das Prog nicht.
Wenn ich aber auf (charcaste dann übersetzt er zwar, aber gibt dann ein Debug-Fehler aus: Invalid allocation size.
Das ist in C++ so, nicht jedoch in C. Wie kompilierst du denn?
In C wird void* implizit in jeden anderen Zeigertypen gecastet.
In C++ musst du void* explizit in einen anderen Zeigertypen casten.
-
Also eigentlich programmiere ich in C.
-
Und wie kompilierst du bitte? Ärgerlich, wenn man Fragen doppelt stellen muss.
-
Sorry, aber dann scheine ich die Frage nicht zu verstehen
?Ich drücke den Debuggen starten Knopf bzw. F5 in Visual Studio und kompiliere im Debug Modus?
-
Also mit Visual Studio. Hast du auch daran gedacht in den Projektoptionen einzustellen, dass du den Code als C-Code und nicht als C++-Code kompilieren willst? Dies geht unter der Rubrik "C/C++" in den Projektoptionen. Am besten auch gleich die Warnstufe hochstellen.
-
Saul schrieb:
Sorry, aber dann scheine ich die Frage nicht zu verstehen
?Ich drücke den Debuggen starten Knopf bzw. F5 in Visual Studio und kompiliere im Debug Modus?Schalte in den Projekteinstellungen einfach um auf den C-Compiler (im Moment nutzt du nämlich den C++-Compiler; C ist eben doch nicht ganz eine Teilmenge von C++, wie du gerade merkst).
Du findest das hier: C/C++ => Erweitert => Kompilierungsart
-
Ok, habe ich befolgt. Aber nun bekomme ich : bzw. { Syntaxfehler in den Dateien cstdio und cstdlib.
-
Saul schrieb:
Ok, habe ich befolgt. Aber nun bekomme ich : bzw. { Syntaxfehler in den Dateien cstdio und cstdlib.
"cstdio" und "cstdlib" gibt es in C nicht. Das sind C++ Header.
Richtig wären "stdio.h" und "stdlib.h".