PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Array-Elemente in einen dynamischen String kopieren?


mf_2
2004-02-12, 15:58:07
Hallo,

Ich habe ein eindimensionales Array test[20].
Ich möchte nun die Elemente [0] - [4] in einen dynamischen String test2 kopieren. Wie geht das?

Hier mal ein exemplarischer Inhalt der array-elemente:

test[0] = H
test[1] = a
test[2] = l
test[3] = l
test[4] = o

Das soll dann als "Hallo" in den String. Geht das?

Brillus
2004-02-12, 16:06:49
mit strcpy oder strncpy Edit: wobei bei disen Funktionen das erste Arry das Ziel ist und das 2. die Quelle

wobei man bein 2. auch noch angibt wieviele zeichen man Kopieren will.

oder Halt per for -schleife

For(int i=0;i<ANZAHLZEICHEN;i++)
{
test[i]=test2[i]
}

Nach meinen wissen macht strcpy und strncpy noch ein '\0' dahinter wobei bei der andern Methode es nicht geschieht.

Muss halt wissen was du willst

mf_2
2004-02-12, 16:30:02
Mit einer for-Schleife hatte ich es auch schon versucht, aber dann stürzt das Programm ab, eine Fehlermeldung erscheint und der Debugger startet.

mf_2
2004-02-12, 17:50:22
Ich hab den Fehler gefunden:

Statt test[i]=test2[i] habe ich mal test=test2[i] ausprobiert. Das geht. Eine Frage: Gibt es sowas wie den Operator ".=" in PHP auch für C? Also dass etwas an den String drangehängt wird?

Gnafoo
2004-02-12, 19:10:29
Poste mal deinen Code, das hilft denke ich weiter.

Denn es gibt keine dynamischen Strings in C. Jeder String
ist ein Array von Chars. Ich denke mal du hast einfach
einen undefinierten Pointer auf char genommen und Werte
in einen nicht allokierten Speicher geschrieben, oder
so etwas ähnliches.

Zum dranhängen eines Strings an einen anderen kann man
strcat benutzen.

cu DerTod

mf_2
2004-02-12, 20:08:49
Ich hab das jetzt mal mit strcat() versucht, aber ich bekomm den folgenden Fehler:

[C++ Error] datei.c(143): Type mismatch in parameter '__dest' in call to 'strcat'.

Ein Auszug aus meinem Programm:

char test[20] = "Hallo";
char *test2;
int anzahl=4;
int main()
{

for (i=0;i<anzahl;i++)

{

test2=strcat(test[i],test2);

}

return 0;

}

So, das ist der problematische Teil des Programms.
Dieser Programmteil soll die ersten 5 Zeichen von test in den dynamischen String test2 schreiben.
Kann das so überhaupt funktionieren?

Xmas
2004-02-12, 20:33:16
Original geschrieben von mf_2
Ich hab das jetzt mal mit strcat() versucht, aber ich bekomm den folgenden Fehler:

[C++ Error] datei.c(143): Type mismatch in parameter '__dest' in call to 'strcat'.

Ein Auszug aus meinem Programm:

char test[20] = "Hallo";
char *test2;
int anzahl=4;
int main()
{

for (i=0;i<anzahl;i++)

{

test2=strcat(test[i],test2);

}

return 0;

}

So, das ist der problematische Teil des Programms.
Dieser Programmteil soll die ersten 5 Zeichen von test in den dynamischen String test2 schreiben.
Kann das so überhaupt funktionieren?
Nein. Es gibt in C keine "dynamischen Strings". Der Speicherplatz muss (fast) immer schon vorher reserviert sein. Entweder in Form eines statisch angelegten Arrays oder mit malloc u.ä.

test2 ist in deinem Fall ein Pointer "nach nirgendwo", der nicht initialisiert ist, also bekommst du beim Zugriff wohl gleich eine Access Violation. Oder zumindest würdest du bekommen, wenn du strcat richtig verwenden würdest.

Um die (maximal) ersten 5 Zeichen von einem String in einen anderen zu kopieren, nimmst du am besten strncpy.


int main() {
char test1[] = "Hallo";
char test2[6];
strncmp(test2, test1, 5);
test2[5] = 0;
return 0;
}

mf_2
2004-02-12, 20:43:08
Jetzt hab ich das so versucht wie du gesagt hast und hab ne Access Violation bekommen. Was ist malloc?
BTW: ist es auch möglich, erst in der mitte der funktion einen string zu definieren ( ihm zu sagen, wieviele zeichen er haben sol)?

Xmas
2004-02-12, 21:37:47
Original geschrieben von mf_2
Jetzt hab ich das so versucht wie du gesagt hast und hab ne Access Violation bekommen. Was ist malloc?
BTW: ist es auch möglich, erst in der mitte der funktion einen string zu definieren ( ihm zu sagen, wieviele zeichen er haben sol)?
Was genau hast du versucht?

Ja, es ist möglich erst während der Programmausführung den Speicher für einen String zu reservieren, eben mit malloc (oder auch new in C++). malloc() reserviert eine bestimmte Anzahl Bytes auf dem Heap und gibt einen Pointer auf diesen Speicherbereich zurück. Allerdings darf man nicht vergessen, den Speicher später mit free() wieder freizugeben.

Ein Beispiel:

int main() {
char * stringbuffer;
/* ... */
stringbuffer = malloc(15); /* 15 Bytes reservieren */
/* hier den Speicherbereich verwenden ... */
stringbuffer[0] = 'H';
stringbuffer[1] = 'i';
stringbuffer[2] = '\0';
printf(stringbuffer);
/* ... */
free(stringbuffer); /* !!! */
return 0;
}

Legolas
2004-02-13, 10:15:20
Ein malloc ohne Fehlerabfrage und mit einem konstanten Wert initialisiert...

In der Uni würdens uns das um die Ohren hauen ;).

mf_2
2004-02-13, 13:09:51
So, das malloc bringt mir noch 2 warnungen ( aber keine fehler):

Call to function malloc() with no prototype
und
Nonportable pointer conversion.
Wie werd ich die los?

BTW: das mit dem "no prototype" bekomm ich öfter, an was liegt das?

Legolas
2004-02-13, 14:54:19
Original geschrieben von mf_2
So, das malloc bringt mir noch 2 warnungen ( aber keine fehler):

Call to function malloc() with no prototype
und
Nonportable pointer conversion.
Wie werd ich die los?

BTW: das mit dem "no prototype" bekomm ich öfter, an was liegt das?

Also ich würde das so machen:

int main() {
char * stringbuffer;
/* ... */
stringbuffer = (char *) malloc(15 * sizeof(char)); /* 15 Bytes reservieren */
/*Fehlerabfrage für malloc*/
if(stringbuffer == NULL){
printf("Fehler!");
exit(1);
}
/* hier den Speicherbereich verwenden ... */
stringbuffer[0] = 'H';
stringbuffer[1] = 'i';
stringbuffer[2] = '\0';
printf(stringbuffer);
/* ... */
free(stringbuffer); /* !!! */
return 0;
}


Die Fehlermeldung mit "no prototype" hört sich nach einem vergessenen include an, schreib also das noch am Anfag der *.c Datei:

"#include <stdlib.h>"

(aber ohne Strichpunkt).

Da du aber weißt, wie lange dein String sein soll, wäre es einfacher einfach ein char stringbuffer[5] (4 Zeichen + Stringendezeichen) zu initalisieren, dann wird der Speicher fest auf dem Stack reserviert und du kannst dir den ganzen malloc-Block sparen.

Xmas
2004-02-13, 14:57:34
Original geschrieben von Legolas
Ein malloc ohne Fehlerabfrage und mit einem konstanten Wert initialisiert...

In der Uni würdens uns das um die Ohren hauen ;).
Wie gesagt, ein Beispiel ;) Für die Stringgröße jetzt noch ein #define hinzuschreiben (konstant darf der Wert ja schon sein, ist allerdings nicht immer sinnvoll) war ich einfach zu faul. Und den Rückgabewert prüfen — welch archaisches Konstrukt! Da lob ich mir Exception-Handling...

Xmas
2004-02-13, 14:59:08
Legolas, du willst doch nicht ein einzelnes Byte reservieren? ;)

Legolas
2004-02-13, 17:54:53
Original geschrieben von Xmas
Wie gesagt, ein Beispiel ;) Für die Stringgröße jetzt noch ein #define hinzuschreiben (konstant darf der Wert ja schon sein, ist allerdings nicht immer sinnvoll) war ich einfach zu faul. Und den Rückgabewert prüfen — welch archaisches Konstrukt! Da lob ich mir Exception-Handling...

Ist ja auch nicht ganz ernst gemeint :). Man sollte nur Anfängern imho gleich zeigen, wie man es richig machen sollte. Und wenn dir das prüfen des Rückgabewertes nicht passt, dann benutz' nicht Ansi-C :).

Original geschrieben von Xmas
Legolas, du willst doch nicht ein einzelnes Byte reservieren? ;)
gefixt :)

Xmas
2004-02-13, 18:58:14
Original geschrieben von Legolas
Ist ja auch nicht ganz ernst gemeint :). Man sollte nur Anfängern imho gleich zeigen, wie man es richig machen sollte. Und wenn dir das prüfen des Rückgabewertes nicht passt, dann benutz' nicht Ansi-C :).
Tu ich ja auch nicht mehr, es sei denn ich werde dazu gezwungen ;)
Und ich empfehle es auch keinem anderen.


Ob das mit sizeof(char) jetzt aber besser ist... sizeof(char) ist ja per ANSI-C Definition immer 1, also kann man auch gleich die Byteanzahl angeben.

Legolas
2004-02-13, 19:23:52
Original geschrieben von Xmas
Ob das mit sizeof(char) jetzt aber besser ist... sizeof(char) ist ja per ANSI-C Definition immer 1, also kann man auch gleich die Byteanzahl angeben.

Bei uns in der Uni hats immer geheißen, das kann eventuell von Compiler zu Compiler unterschiedlich sein. Deswegen die sizeof()-Abfrage. v.a. wenn man Integers oder Ahnliches betrachtet, ist das wohl öfters so und es ist wohl besser, wenn man sich das dann gleich so konsequent angewöhnt.

mf_2
2004-02-13, 19:40:31
Danke für die zahlreichen Antworten, jetzt funktionierts!

Legolas
2004-02-13, 19:49:39
Hier noch ein Link, der mir bis jetzt schon ziemlich viel geholfen hat:

http://pronix.de/modules/C/openbook/