Fragen zu Strings in C

Hallo zusammen!
Die erste Programmiersprache die ich gelernt habe war Visual Basic. Gerade bin ich dabei mich in C und C++ einzuarbeiten. Aus Basic kenne ich viele komfortable String-Funktionen. Das gibt es so in C ja nicht. Alleine schon string1 = string2 + string3 führt zu einem Fehler. Mit einem C-Buch habe ich mich jetzt einigermaßen an die Nachteile aber auch Vorteile von Strings in C gewöhnt. Zu dem nachstehenden Quelltext in C (nicht C++) habe ich drei Fragen, wobei diese als Kommentare im Quelltext eingebettet sind und würde mich freuen wenn mir jemand helfen könnte:

#include
#include
#include

int main(int argc, char *argv[]){

int x;
char str1[] = „Hello World!“;
char str2[] = "First part ";
char str3[] = „of a splitted string.“;
char str4[] = „This PC runs my programm!“;

/* str1 soll rückwärtsgeschrieben ausgegeben werden: */
char buffer1[sizeof(str1)];
/* Wenn ich das Programm debuge enthält an dieser Stelle buffer1 den Wert von str4. Warum ist das so und ist das richtig? */
for(x = sizeof(str1) - 2; x >= 0; x–) buffer1[sizeof(str1) - 2 - x] = str1[x];
buffer1[sizeof(str1) - 1] = 0;
/* Obwohl buffer1 die Größe von str1 besitzt stehen nach „!dlroW olleH“ ohne den Befehl „buffer1[sizeof(str1) - 1] = 0“ noch ein paar Hieroglyphen und dann der Inhalt von str4. Das hieße ja aber das buffer1 größer ist als str1. Quasi schiebt das Programm str4 nach rechts und setzt meinen Text und ein paar Hieroglyphen davor. Warum ist das so und kann ich das irgendwie verhindern? Oder anders gefragt, wie muss das richtig aussehen damit zum einen bufer1 wirklich die Größe von str1 besitzt und str4 darin nicht mehr auftaucht? */
printf("%s %s\n", str1, buffer1);

/* In str4 ist „PC“ durch „computer“ zu ersetzen. Dazu muss als erstes die Position von „PC“ in str4 ermittelt werden, dann das Array str4 in seiner Dimension vergrößert werden und schließlich „PC“ ersetzen: */
char buffer3[] = „PC“;
char buffer4[] = „computer“;
char buffer5[sizeof(str4) - sizeof(buffer3) + sizeof(buffer3)] = „“;
memcpy(buffer5, str4, strlen(str4) - strlen(strstr(str4, buffer3)));
strcat(buffer5, buffer4);
strcat(buffer5, strchr(strstr(str4, buffer3), ’ '));
printf("‚PC‘ replaced by ‚computer‘: %s\n", buffer5);
/* Die Frage hierzu ist recht simple: Aus Visual Basic kenne ich die mid-Funktion, die das macht was ich hier programmiert habe. In C gibt es eine solche Funktion nicht. Meine Frage ist nun ob das nicht auch eleganter geht, vor allem im Hinblick auf aufwendige Programme und Rechnerressourcen? */

return 0;

}

// Grüße C. Penkwitt

Hallo zusammen!
Die erste Programmiersprache die ich gelernt habe war Visual
Basic. Gerade bin ich dabei mich in C und C++ einzuarbeiten.

In beide gleichzeitig? dann solltest du sehr gut aufpassen, sie nicht zu verwechseln (s.u.), am besten du lernst eins nach dem anderen…

Aus Basic kenne ich viele komfortable String-Funktionen. Das
gibt es so in C ja nicht.

Jain. Sie sind nicht in die Sprache eingebaut, sondern sind in den Standardbibliotheken „versteckt“. Dadurch sind sie nicht ganz so komfortabel anzusprechen, aber es gibt sie. Wenn du die C+±Klasse string verwendest, bekommst du viel vom Komfort wieder zurück :wink:

> #include   
> #include   
> #include   
>   
> int main(int argc, char \*argv[]){  
>   
> int x;  
> char str1[] = "Hello World!";  
> char str2[] = "First part ";  
> char str3[] = "of a splitted string.";  
> char str4[] = "This PC runs my programm!";  
>   
> /\* str1 soll rückwärtsgeschrieben ausgegeben werden: \*/  
> char buffer1[sizeof(str1)];  
> /\* Wenn ich das Programm debuge enthält an dieser Stelle  
> buffer1 den Wert von str4. Warum ist das so und ist das  
> richtig? \*/  
> for(x = sizeof(str1) - 2; x \>= 0; x--)  
> buffer1[sizeof(str1) - 2 - x] = str1[x];

Willst du denn buffer1 als „umgedrehten“ str1 haben?
wenn nicht, kannst du buffer1[x] = str1[x]; schreiben.
Aber wieso verwendest du nicht strcpy bzw. strncpy?

So, für die anderen darf jemand anderes ran… :wink:

Grüße,
Moritz

Hallo Christian!

Vorab ein paar Bemerkungen zu Strings in C. Nahezu alle Funtionen der RunTimeLib arbeiten nur mit 0 terminierten Strings. Wenn du irgendwo vergisst die Null am Ende hinzuschreiben oder sie überschreibst machen alle Funktionen dann gröbsten Unfug.
Z.B. printf("%s", string); wird solange Character an die Console schicken bis das erste mal wirklich eine Null im string auftaucht.

#include
#include
#include

int main(int argc, char *argv[]){

int x;
char str1[] = „Hello World!“;
char str2[] = "First part ";
char str3[] = „of a splitted string.“;
char str4[] = „This PC runs my programm!“;

/* str1 soll rückwärtsgeschrieben ausgegeben werden: */
char buffer1[sizeof(str1)];
/* Wenn ich das Programm debuge enthält an dieser Stelle
buffer1 den Wert von str4. Warum ist das so und ist das
richtig? */

Da Du buffer1 nicht initialisiert hast ist der Inhalt völlig zufällig (naja fast).
char buffer1[sizeof(str1)] = „“;

for(x = sizeof(str1) - 2; x >= 0; x–)
buffer1[sizeof(str1) - 2 - x] = str1[x];
buffer1[sizeof(str1) - 1] = 0;
/* Obwohl buffer1 die Größe von str1 besitzt stehen nach
„!dlroW olleH“ ohne den Befehl „buffer1[sizeof(str1) - 1] = 0“
noch ein paar Hieroglyphen und dann der Inhalt von str4. Das
hieße ja aber das buffer1 größer ist als str1. Quasi schiebt
das Programm str4 nach rechts und setzt meinen Text und ein
paar Hieroglyphen davor. Warum ist das so und kann ich das
irgendwie verhindern? Oder anders gefragt, wie muss das
richtig aussehen damit zum einen bufer1 wirklich die Größe von
str1 besitzt und str4 darin nicht mehr auftaucht? */

buffer1 hat die Größe von str1, nur wie oben schon erwähnt, wenn die terminierende Null fehlt wird hat immer weiter gelesen. Offensichtlich hat dein Compiler str4 hinter buffer1 im Speicher gelegt und so siehst du den Inhalt danach von str4. Die Hyroglyphen würde ich mal als alignment Bytes interpretieren.
Leichter geht es übrigens mit strrev(str1).

printf("%s %s\n", str1, buffer1);

/* In str4 ist „PC“ durch „computer“ zu ersetzen. Dazu muss
als erstes die Position von „PC“ in str4 ermittelt werden,
dann das Array str4 in seiner Dimension vergrößert werden und
schließlich „PC“ ersetzen: */
char buffer3[] = „PC“;
char buffer4[] = „computer“;
char buffer5[sizeof(str4) - sizeof(buffer3) +
sizeof(buffer3)] = „“;
memcpy(buffer5, str4, strlen(str4) - strlen(strstr(str4,
buffer3)));
strcat(buffer5, buffer4);
strcat(buffer5, strchr(strstr(str4, buffer3), ’ '));
printf("‚PC‘ replaced by ‚computer‘: %s\n", buffer5);
/* Die Frage hierzu ist recht simple: Aus Visual Basic kenne
ich die mid-Funktion, die das macht was ich hier programmiert
habe. In C gibt es eine solche Funktion nicht. Meine Frage ist
nun ob das nicht auch eleganter geht, vor allem im Hinblick
auf aufwendige Programme und Rechnerressourcen? */

So eine mid-Funktion gibt es in C nicht (soweit ich weiß) aber man kann sie sich doch recht einfach hinschreiben, mach dir doch deine eigene strmid() Funktion.
Hast du dir mal überlegt was passiert wenn buffer3 nicht in str4 gefunden wird?

Gruß
Stefan

So eine mid-Funktion gibt es in C nicht (soweit ich weiß) aber
man kann sie sich doch recht einfach hinschreiben, mach dir
doch deine eigene strmid() Funktion.
Hast du dir mal überlegt was passiert wenn buffer3 nicht in
str4 gefunden wird?

Hallo Stefan!
Vielen Dank für deine schnelle Hilfe. Meine ersten beiden Fragen hast du vollständig klären können. Mir jetzt auch klar geworden warum das so ist wie es ist. Bei der mid-Funktion würde ich aber gerne noch Mal nachfragen:
Also streng genommen ist das was ich programmiert habe nicht die echte mid-Funktion aus Basic sondern die instr-Funktion aus Delphi. Wenn der String nicht gefunden wird sollte die Funktion NULL zurückgeben ansonsten die Position im String an der buffer3 gefunden wurde. Aber ich bin immer noch nicht davon überzeugt dass dies die ressourcenschonenste und eleganteste Lösung ist.
Stell dir mal vor ich möchte ein ganzes Intranet parsen und würde pro Webseite diese Funktion zehn Mal benutzen. Gibt es dann wirklich nichts Besseres? Wie hättest du die gestellte Aufgabe in C gelöst? Also suche buffer3 im String str4 und ersetze buffer3 durch buffer4, wobei im allgemeinen buffer3 und buffer4 nicht die gleiche Größe haben?

Grüße
C. Penkwitt

Jain. Sie sind nicht in die Sprache eingebaut, sondern sind in
den Standardbibliotheken „versteckt“. Dadurch sind sie nicht
ganz so komfortabel anzusprechen, aber es gibt sie. Wenn du
die C+±Klasse string verwendest, bekommst du viel vom Komfort
wieder zurück :wink:
Willst du denn buffer1 als „umgedrehten“ str1 haben?
wenn nicht, kannst du buffer1[x] = str1[x]; schreiben.
Aber wieso verwendest du nicht strcpy bzw. strncpy?

Hallo Moritz!
Nein, es war schon so gedacht das buffer1 den String str1 in umgekehrter Reihenfolge enthält. Dieses Programm sollte ja lediglich als Übung für Strings in C dienen. Trotzdem Danke.

Grüße
C. Penkwitt

PS.: Mit den Standardbibliotheken meinst du schon ctype.h und string.h, oder?

Hallo Christian!

Stell dir mal vor ich möchte ein ganzes Intranet parsen und
würde pro Webseite diese Funktion zehn Mal benutzen. Gibt es
dann wirklich nichts Besseres? Wie hättest du die gestellte
Aufgabe in C gelöst? Also suche buffer3 im String str4 und
ersetze buffer3 durch buffer4, wobei im allgemeinen buffer3
und buffer4 nicht die gleiche Größe haben?

Wenn du dies in der folgender Art schreibst, solltest du keine Probleme haben. Nur so als ersten Gedankenentwurf zu verstehen!

int ErsetzeEinWort( char *cpSrc, char *cpDst, int iDstLen, char *cpSearch, char *cpReplace )
{
int length, x;

length = strlen(cpSrc)
for (x = 0; x

Hallo Stefan!
Vielen Dank! Es funktioniert einwandfrei! Das mit der Performance ist so eine Sache finde ich. Wenn man keine Alternativen hat nimmt man halt was man bekommt, aber bei C scheint das ja zum Glück anders zu sein …
Vielen Dank noch mal und dir viel Spaß im U…!

Grüße
C. Penkwitt