Character aus String entfernen
-
supertux schrieb:
1. wenn du C++ benutzt, dann verwende auch std::string. C mit C++ zu kompilieren ist wie an einem Autorally-Rennen mit einem Dreirad teilzunehmen.
Ich habe das zwar mit dem G++ kompiliert, aber da das ja im ANSI C-Forum ist, wollte ich schon die C-Funktionen benutzen. Gibt es mit dem C-Compiler Unterschiede?
supertux schrieb:
one
zeigt auf Read-Only Memory. Du musstone
entweder als Array deklarieren oder Speicher dynamisch anfordern.
Aha, interessant. Werde das gleich mal ausprobieren.
supertux schrieb:
strcpy
erwartet Memory-Bereiche, die sich nicht überlappen. Dafür gibt es man: memmove(3), was in diesem Fall benutzt werden soll.
Ach ja, daran habe ich auch gedacht, wusste aber nicht mehr, wie rum das Ganze war.
-
So sieht das Ganze dann auch schon deutlich besser aus. Danke!
char one[] = "Hello World!"; char *pos = strchr(one, 'W'); memmove(pos, pos+1, strlen(one) - (unsigned long)(pos - one)); cout << one;
-
wxSkip schrieb:
supertux schrieb:
1. wenn du C++ benutzt, dann verwende auch std::string. C mit C++ zu kompilieren ist wie an einem Autorally-Rennen mit einem Dreirad teilzunehmen.
Ich habe das zwar mit dem G++ kompiliert, aber da das ja im ANSI C-Forum ist, wollte ich schon die C-Funktionen benutzen. Gibt es mit dem C-Compiler Unterschiede?
Du solltest dich für eine Sprache entscheiden. C oder C++? Du benutzt dort "cout", was ein std::ostream ist - also C++. Allerdings willst du mit C-Strings hantieren, also C-Kram. Was denn nun?
-
Oh, das cout hatte ich nicht bemerkt, das habe ich ja bloß zum Testen verwendet, der Fragesteller will ja C benutzen.
-
wxSkip schrieb:
supertux schrieb:
1. wenn du C++ benutzt, dann verwende auch std::string. C mit C++ zu kompilieren ist wie an einem Autorally-Rennen mit einem Dreirad teilzunehmen.
Ich habe das zwar mit dem G++ kompiliert, aber da das ja im ANSI C-Forum ist, wollte ich schon die C-Funktionen benutzen. Gibt es mit dem C-Compiler Unterschiede?
natürlich, C ist nicht C++ und C++ ist nicht C. Acuh wenn C++ eine große Kompabilität zu C hat, sit es nicht weise, C und C++ zu mischen, weil die Fehler umso schwer zu finden sind, wenn man Verhalten A erwartet und davon ausgeht, dass A eintritt, aber in Wirklichkeit etwas ganz anders passiert.
Hier ein Bsp:
#include <stdio.h> int main(void) { printf("C%s\n", sizeof(1==1) == 1 ? "++" : ""); return 0; }
$ gcc -otest c.c ./test C $ g++ -otest c.c ./test C++
-
Janjan schrieb:
"char" ist ein einzelnes Zeichen.
Jetzt kapier ich gar nichts mehr.
Wie kann ich denn dann den Output aus strchr() (in memmove) weiterverwenden?
-
Schnapp dir dein Buch und schlag das Kapitel über Zeiger nach. Dann lies noch die Dokumentationen zu den einzelnen Befehlen. Wenn du jetzt noch dein Hirn einschaltest und überlegst was du eigentliche machen willst und mit bestimmten Code machst, dann bist du der Lösung schon einen großen Schritt weiter.
-
Janjan schrieb:
Schnapp dir dein Buch und schlag das Kapitel über Zeiger nach. Dann lies noch die Dokumentationen zu den einzelnen Befehlen. Wenn du jetzt noch dein Hirn einschaltest und überlegst was du eigentliche machen willst und mit bestimmten Code machst, dann bist du der Lösung schon einen großen Schritt weiter.
Ich schlage im Gegenzug vor, dass ihr mir sagt, in welchem Forum man als Anfänger bessere Hilfe bekommen kann. Die Antworten hier im Forum sind etwas zu fortgeschritten für meinen Geschmack und auf 'RTFM' wäre ich auch selbst gekommen.
-
sega schrieb:
...
Jetzt kapier ich gar nichts mehr.
Wie kann ich denn dann den Output aus strchr() (in memmove) weiterverwenden?Ein char ist kein char*. Die Funktion strchr gibt einen Zeiger auf char, also einen char* zurück.
Die Funktion memmove erwartet zwei Zeiger und die Anzahl der Bytes, die verschoben werden; der Typ der Zeiger ist jedoch uninteressant (darum sind die Zeigertypen in memmove void*).
Die Funktion strchr gibt also einen Zeiger zurück, die Funktion memmove will Zeiger haben, alles prima.
-
strchr() gibt keinen char zurück, sondern einen Zeiger auf einen char.
Das heißt hinter dem char, dessen Adresse der Zeiger speichert, steht der Rest des Strings. Und damit kannst du was anfangen.PS: Ich glaube, wenn man ein paar Hundert Beiträge mehr geschrieben hat als ich, nervt es viele auch ein bisschen, wenn immer die gleichen Fragen zu Zeigern usw. auftauchen. Schließlich steht das alles schon in vielen Büchern geschrieben, warum sollte man sich immer wiederholen?
Ich persönlich kann dir nur zu einem Buch raten, in anderen Foren wird es auch nicht anders sein, schließlich tritt man einem Forum ja nicht nach Gutmütigkeit oder Geduldigkeit bei, sondern nach Thema.
-
sega schrieb:
Janjan schrieb:
Schnapp dir dein Buch und schlag das Kapitel über Zeiger nach. Dann lies noch die Dokumentationen zu den einzelnen Befehlen. Wenn du jetzt noch dein Hirn einschaltest und überlegst was du eigentliche machen willst und mit bestimmten Code machst, dann bist du der Lösung schon einen großen Schritt weiter.
Ich schlage im Gegenzug vor, dass ihr mir sagt, in welchem Forum man als Anfänger bessere Hilfe bekommen kann. Die Antworten hier im Forum sind etwas zu fortgeschritten für meinen Geschmack und auf 'RTFM' wäre ich auch selbst gekommen.
Nirgends? Junge, wenn du was gebacken haben willst, musst du schon Eigenleistung zeigen. Was würde dir bringen, wenn man dir alles aufm Silbertablett presentiert? Nichts.
Was Janjan schrieb klingt sehr harsch aber glaub mir, er hat mit der Sache 100% Recht und wenn du selbst auf RTMF gekommen bist, wieso tust du das denn nicht? erwartet nicht von uns, uns das Lernen zu überlassen. Denken, überlegen, usw. musst du nämlich immer noch selber. Dran führt kein Weg vorbei und wenn du das nicht einsiehst, wirst du früher als später scheitern.
-
Alles klar, ich frage nicht weiter.
Thread bitte schließen.
-
wieso tust du hier die beleidigte Wurst ab?
-
Lass ihn doch, wahrscheinlich hat er sich das Ganze mit dem Forum anders vorgestellt...
-
Allerdings, und beleidigt würde ich das nicht nennen.
Eher einsichtig, ich bin ja jetzt informiert: http://www.c-plusplus.net/forum/viewtopic-var-t-is-136013.html
-
wxSkip schrieb:
strchr() gibt keinen char zurück, sondern einen Zeiger auf einen char.
Das heißt hinter dem char, dessen Adresse der Zeiger speichert, steht der Rest des Strings. Und damit kannst du was anfangen.PS: Ich glaube, wenn man ein paar Hundert Beiträge mehr geschrieben hat als ich, nervt es viele auch ein bisschen, wenn immer die gleichen Fragen zu Zeigern usw. auftauchen. Schließlich steht das alles schon in vielen Büchern geschrieben, warum sollte man sich immer wiederholen?
Ich persönlich kann dir nur zu einem Buch raten, in anderen Foren wird es auch nicht anders sein, schließlich tritt man einem Forum ja nicht nach Gutmütigkeit oder Geduldigkeit bei, sondern nach Thema.Erstmal: Das Kapitel über Zeiger (C von A bis Z) habe ich jetzt gelesen.
Dachte auf den ersten Blick ich könnte meine Probleme mit diesem Indirektionsoperator lösen - leider nicht.
Aus der CSV-Textdatei kommen zeilenweise Daten (im char c[10000]), die ich mit
strToken(c,";",lineToken);
von ihren Trennzeichen befreie. Die Funktion sieht so aus:
int strToken(char *str, char *separator, char *token[]) { int i = 0; token[0] = strtok(str,separator); while ( token[i] ) { i++; token[i] = strtok(NULL, separator); } return ( i ); }
Das lineToken ist bei mir ein pointer (char *lineToken[1000]).
Wenn ich auf lineToken[0] zugreife bekomme ich die Ausgabe: #1.
Genau richtig, denn er erste Eintrag in der CSV-Datei ist #1.Jetzt möchte ich diesen Eintrag (also #1) vom Zeichen # befreien. So gedacht:
char *pos; pos = strchr(lineToken[0],'#'); if (pos != NULL){ memmove(pos,pos+1,strlen(pos)); }
Läuft leider nicht, weil der pos immer NULL ist.
Dachte zumindest im memmove müsste dann an Stelle von pos, *pos stehen, aber bis dahin kommt das Programm ja schon nicht.
Falls noch jemand bereit ist was dazu zu sagen, würde ich mich freuen.
-
Das memmove stimmt schon, kannst du mal den relevanten Codeausschnitt am Stück posten? Mir ist der Fehler nicht ersichtlich.
-
Das hier ist der ganze Abschnitt:
DEFINE_ON_DEMAND(readFile) { char *pos; int i = 0; int zeile = 0; /* Zeilennummer in der Datei */ char *lineToken[1000]; /* Teile einer Zeile */ char c[10000]; /* Char-Array, in dem der Dateiinhalt ZEILENWEISE abgelegt werden */ FILE *file; file = fopen("reacdat.csv", "r"); if(file==NULL) { Message0("Error: can't open file.\n"); /* fclose(file); DON'T PASS A NULL POINTER TO fclose !! */ } else { Message0("File opened successfully. Contents:\n\n"); while(fgets(c, 10000, file)!=NULL) { /* Schleife durch die Zeile, bis zum NULL-Pointer */ /* Das Zeilenende wird als NULL-Pointer (Error) gewertet */ zeile++; strToken(c,";",lineToken); /* Ab hier liegt die Zeile aufgespaltet in lineToken vor */ if (zeile == 18){ Message0("Zeile 18\n"); Message0("Eintrag 1: %s.\n",lineToken[0]); } Message0("lineToken[0]: %s\n",lineToken[0]); pos = strchr(lineToken[0],'#'); if (pos != NULL){ memmove(pos,pos+1,strlen(pos)); } } Message0("\n\nNow closing file...\n"); fclose(file); } } int strToken(char *str, char *separator, char *token[]) { int i = 0; token[0] = strtok(str,separator); while ( token[i] ) { i++; token[i] = strtok(NULL, separator); } return ( i ); }
-
So, bei mir funktioniert dieser Code:
int strToken(char *str, const char *separator, char *token[]) { int i = 0; token[0] = strtok(str,separator); while ( token[i] ) { i++; token[i] = strtok(NULL, separator); } return ( i ); } int main() { char *pos; int zeile = 0; /* Zeilennummer in der Datei */ char *lineToken[1000]; /* Teile einer Zeile */ char c[10000]; /* Char-Array, in dem der Dateiinhalt ZEILENWEISE abgelegt werden */ FILE *file; file = fopen("bsp.txt", "r"); if(file==NULL) { printf("Error: can't open file.\n"); /* fclose(file); DON'T PASS A NULL POINTER TO fclose !! */ } else { printf("File opened successfully. Contents:\n\n"); while(fgets(c, 10000, file)!=NULL) { /* Schleife durch die Zeile, bis zum NULL-Pointer */ /* Das Zeilenende wird als NULL-Pointer (Error) gewertet */ zeile++; strToken(c,";",lineToken); /* Ab hier liegt die Zeile aufgespaltet in lineToken vor */ if (zeile == 18){ printf("Zeile 18\n"); printf("Eintrag 1: %s.\n",lineToken[0]); } printf("lineToken[0]: %s\n",lineToken[0]); pos = strchr(lineToken[0],'#'); if (pos != NULL){ memmove(pos,pos+1,strlen(pos)); } else printf("pos == NULL\n"); } printf("\n\nNow closing file...\n"); fclose(file); } }
mit diesem Dateiinhalt:
asfd#asdf;abc;def;ghi
-
Hm, sehe da gar keinen Unterschied.
Warum klappt das bei mir nicht?Das ist übrigens der Dateiinhalt:
#1;FeS[s];#;#;#;#;#; ===>;Fe[s];0.5 S2[g];#;#;#;#
Gibts Probleme, weil das zu entfernende Zeichen am Anfang steht?