Character aus String entfernen
-
supertux schrieb:
char one[] = "#1"; pos = strchr(one,'#'); if(pos) memmove(pos,pos+1,strlen(pos)+1); // damit \0 mitkopiert wird
Wirklich '+1'?
Er beginnt doch bereits bei 'pos+1', nicht pos,...
-
Danke!
Ich hätte mich mal an den Forum-Kodex halten sollen und nicht nur Minimal-Code ausgeben sollen.
Tatsächlich liegt das Programm so vor, dass strchr schon NULL zurück gibt, weil der string dort als pointer ankommt.
Klingt seltsam, liegt aber daran das vorgeschaltet schon eine Funktion abgelaufen ist, die einen String von Trennzeichen befreit und dann die Zwischeneinträge preisgibt (lineToken), was aber pointer verlangt und ausspuckt.
Diese Einträge möchte ich dann wieder mit strchr und memmove weiter bearbeiten.
Offensichtlich muss ich zwischendurch also aus pointer "richtige" Strings machen.Wie gehts das denn?
DEFINE_ON_DEMAND(readFile) { char *pos; int zeile = 0; char *lineToken[1000]; char c[10000]; 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); /* Aufspalten der Zeile in Token */ /* Ab hier liegt die Zeile aufgespaltet in lineToken vor */ pos = strchr(lineToken[0],'#'); if (pos != NULL){ memmove(pos,pos+1,strlen(pos)+1); } } Message0("\n\nNow closing file...\n"); fclose(file); } } int strToken(char *str, char *separator, char *token[]) { int i = 0; token[0] = strtok(str,";"); while ( token[i] ) { i++; token[i] = strtok(NULL, separator); } return ( i ); }
-
c-hasser&# schrieb:
supertux schrieb:
char one[] = "#1"; pos = strchr(one,'#'); if(pos) memmove(pos,pos+1,strlen(pos)+1); // damit \0 mitkopiert wird
Wirklich '+1'?
Er beginnt doch bereits bei 'pos+1', nicht pos,...Ach ja, stimmt, das zu löschende Zeichen ist ebenfalls mitdrin und da kommt +1 von alleine. Also
strlen(pos)
genügt.
-
sega schrieb:
Offensichtlich muss ich zwischendurch also aus pointer "richtige" Strings machen.
Es gibt in C keine "richtigen" Strings. Es gibt nur char-Pointer. Die zeigen jeweils auf den ersten Character der Zeichenkette. Damit man weiß wann die Zeichenkette zu ende ist, wird jede Zeichenkette mit dem \0-Wert beendet.
-
Janjan schrieb:
sega schrieb:
Offensichtlich muss ich zwischendurch also aus pointer "richtige" Strings machen.
Es gibt in C keine "richtigen" Strings. Es gibt nur char-Pointer. Die zeigen jeweils auf den ersten Character der Zeichenkette. Damit man weiß wann die Zeichenkette zu ende ist, wird jede Zeichenkette mit dem \0-Wert beendet.
Und wie kann ich dann strchr mit einen char an Stelle von char* füttern?
-
sega schrieb:
Janjan schrieb:
sega schrieb:
Offensichtlich muss ich zwischendurch also aus pointer "richtige" Strings machen.
Es gibt in C keine "richtigen" Strings. Es gibt nur char-Pointer. Die zeigen jeweils auf den ersten Character der Zeichenkette. Damit man weiß wann die Zeichenkette zu ende ist, wird jede Zeichenkette mit dem \0-Wert beendet.
Und wie kann ich dann strchr mit einen char an Stelle von char* füttern?
Gar nicht. strstr sucht das erste auftauchen einer Zeichenkette in einer anderen.
"char" ist ein einzelnes Zeichen.
-
sega schrieb:
...
Offensichtlich muss ich zwischendurch also aus pointer "richtige" Strings machen.Der Zeiger muss auf beschreibbaren Speicher zeigen.
char a[] = "Write me!"; // Speicher darf beschrieben werden. char b[20] = "Write me!"; // Speicher darf beschrieben werden. char* c = "Write me an crash!"; // Speicher darf nicht ohne weiteres beschrieben werden.
Allerdings solltest du den dritten Parameter für memmove noch einmal überdenken, weil du nämlich übers Zeichnkettenende hinaus auf Speicherplatz zugreifst, der möglicherweise nicht deinem Programm gehört und einen Programmabsturz verursachen kann ( segmentaton fault ).
char buf[] = "+B+r+o+t+s+p+i+n+n+e+"; char* p; while ( ( p = strchr ( buf, '+' ) ) != NULL ) memmove ( p, p+1, strlen(buf) - (p-buf)); puts ( buf );
-
[quote="Big Brother"]
sega schrieb:
char buf[] = "+B+r+o+t+s+p+i+n+n+e+"; char* p; while ( ( p = strchr ( buf, '+' ) ) != NULL ) memmove ( p, p+1, strlen(buf) - (p-buf)); puts ( buf );
Warum eigentlich überhaupt so? In der Schleife dauernd memmove, strlen und und strchr aufzurufen, ist nicht gerade effizient.
char buf[] = "+B+r+o+t+s+p+i+n+n+e+"; char *dest = buf; for ( src=buf; *src ; ++src ){ if ( *src != '+' ) *dest++=*src; } *dest='\0';
Oder so ähnlich.
-
[quote="
c-hasser&#"]
Big Brother schrieb:
sega schrieb:
char buf[] = "+B+r+o+t+s+p+i+n+n+e+"; char* p; while ( ( p = strchr ( buf, '+' ) ) != NULL ) memmove ( p, p+1, strlen(buf) - (p-buf)); puts ( buf );
Warum eigentlich überhaupt so? In der Schleife dauernd memmove, strlen und und strchr aufzurufen, ist nicht gerade effizient.
nein, aber es macht einfacher zu verstehen, womit man zu tun hat.
-
c-hasser&# schrieb:
Warum eigentlich überhaupt so?
In der Schleife dauernd memmove, strlen und und strchr aufzurufen, ist nicht gerade effizient.Naja, hier ging es darum, ein Zeichen zu entfernen.
Wenn alle gefundenen Zeichen entfernt werden sollen, würde ich es im Prinzip so machen wie du, z.B.char buf[] = "+B+r+o+t+s+p+i+n+n+e+"; char *dest, *src; char to_find = '+'; for ( dest = src = buf; *src; src++ ) if ( *src != to_find ) *dest ++= *src; while ( dest != src ) *dest++ = 0;
-
Sorry, auch ich hab versucht, ein Programm zu schreiben, und steh völlig auf dem Schlauch, hab ich ein Brett vorm Kopf? Bei strcpy bekommt dieses Programm einen Segmentation fault, ich habe es auch schon mit memcpy und memmove versucht.
char *one = "Hello World!"; unsigned long length = strlen(one); char *pos = strchr(one, 'W'); printf("%p\n%p\n", one, pos); cout << pos << end; pos = strcpy(pos, pos+1); cout << "Hello World!" << endl; one[length-1] = '\0'; cout << one;
-
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.
2.one
zeigt auf Read-Only Memory. Du musstone
entweder als Array deklarieren oder Speicher dynamisch anfordern.
3.strcpy
erwartet Memory-Bereiche, die sich nicht überlappen. Dafür gibt es man: memmove(3), was in diesem Fall benutzt werden soll.
-
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.