Forum: PC-Programmierung Zeigerdaten in ein Array schreiben


von TheBeginner (Gast)


Lesenswert?

Hallo zusammen,

bräuchte mal kurz einen Tipp. Rufe eine Funktion auf die mir einen 
String zurückgeben soll, mache das folgendermaßen,

char *connection_establishment(void)
{
  char id_request="ID request";
  char *pointer= (char*)malloc(strlen(id_request)+1);
  strcpy(pointer,id_request);
  return pointer;
}

möchte dann jedes einzehlne Zeichen in ein Array schreiben,

...
test_pointer=connection_establishment;
for(tx_cnt=0;tx_cnt<x;tx_cnt++)   //x, maximale Größe des Strings
{
txbuf[tx_cnt]=test_pointer+tx_cnt; //ins Array schreiben
}
free(test_pointer); //leeren des speichers
...


wollte also zuerst Werte an den test_pointer übergenen, und diese dann 
in ein Array schreiben, zeichenweise. D.h. erste Stelle im Array kriegt 
das erste Zeichen des Strings zugewiesen.

Leider bekomme ich Fehler,

test_pointer=connection_establishment; // assignment from incompatible 
pointer type

char *pointer= (char*)malloc(strlen(id_request)+1); // passing argument 
1 of 'strlen' makes pointer from integer without a cast

weiss eventuell jemand den Grund?

Danke & Gruß

von Karl H. (kbuchegg)


Lesenswert?

TheBeginner schrieb:

> char *connection_establishment(void)
> {
>   char id_request="ID request";
>   char *pointer= (char*)malloc(strlen(id_request)+1);
>   strcpy(pointer,id_request);
>   return pointer;
> }

keine so wahnsinnig gute Idee.
Siehe
http://www.mikrocontroller.net/articles/FAQ#wie_schreibt_man_eine_Funktion.2C_die_einen_String_liefert.3F


> ...
> test_pointer=connection_establishment;

das ist kein Funktionsaufruf.

> for(tx_cnt=0;tx_cnt<x;tx_cnt++)   //x, maximale Größe des Strings

und wer sagt dir, dass der Rückgabestring auch tatsächlich so gross war?
Wenn schon dann müsstest du hier das Minium aus x und strlen vom 
erhaltenen String nehmen.

> {
> txbuf[tx_cnt]=test_pointer+tx_cnt; //ins Array schreiben

wenn du Arrayzugriff machst, dann mach auch Arrayzugriff

    txbuf[tx_cnt] = test_pointer[tx_cnt];
> }
> free(test_pointer); //leeren des speichers
> ...


aber warum so kompliziert?
1
  test_pointer = connection_establishment();
2
  strcpy( txbuf, test_pointer );
3
  free( test_pointer );

noch besser, wenn an dieser Stelle txbuf in seiner Arrayform verfügbar 
ist (und nicht einfach nur ein Pointer ist)
1
  test_pointer = connection_establishment();
2
  strncpy( txbuf, test_pointer, sizeof( txbuf ) );
3
  txbuf[sizeof(txbuf)-1] = '\0';
4
  free( test_pointer );

Aber eigentlich ist auch das ziemlicher Müll.
Die beste Methode ist es meistens, den Buffer in die Funktion 
connection_establishment hinein zu übergeben (zusammen mit seiner 
Länge), und die Funktion soll ihre Ergüsse gleich im Buffer ablegen.
Dann braucht man nicht allokieren und großartig herumkopieren.


> Leider bekomme ich Fehler,
>
> test_pointer=connection_establishment; // assignment from incompatible
> pointer type

logo. Du machst hier keinen Funktionsaufruf

>
> char *pointer= (char*)malloc(strlen(id_request)+1); // passing argument
> 1 of 'strlen' makes pointer from integer without a cast


   char id_request="ID request";
   char *pointer= (char*)malloc(strlen(id_request)+1);


id_request ist ein einzelner Character. Einer!
Wie soll denn da ein kompletter String reinpassen?
1
char *connection_establishment(void)
2
{
3
  char id_request[] = "ID request";
4
5
  char *pointer= (char*)malloc(strlen(id_request)+1);
6
  strcpy(pointer,id_request);
7
  return pointer;
8
}

oder
1
char *connection_establishment(void)
2
{
3
  char* id_request = "ID request";
4
  char *pointer= (char*)malloc(strlen(id_request)+1);
5
  strcpy(pointer,id_request);
6
  return pointer;
7
}


Aber egal wie du es machst: Du brauchst ein C-Buch!

von Klaus W. (mfgkw)


Lesenswert?

TheBeginner schrieb:
> test_pointer=connection_establishment; // assignment from incompatible
> pointer type

um dazu etwas zu sagen, müsste man wissen, wie test_pointer definiert 
ist?

TheBeginner schrieb:
>  char id_request="ID request";
> ...
> char *pointer= (char*)malloc(strlen(id_request)+1); // passing argument
> 1 of 'strlen' makes pointer from integer without a cast

das soll wohl
1
 char *id_request="ID request";
heißen statt
1
 char id_request="ID request";
?

und ja, man darf C-Quelltext in
1
[c]
2
...
3
[/c]
einschließen, dann kann man es ordentlich lesen.

von TheBeginner (Gast)


Lesenswert?

Danke für die Hilfe,

hatte mich da verschriben mit "id_request". Und dem x habe ich die Länge 
des Strings zugewiesen.

von XXX (Gast)


Lesenswert?

Hallo

Dann zeig doch mal dein richtiges Programm und nicht
irgendwas falsch abgeschriebenes.

Gruß
Joachim

von Karl H. (kbuchegg)


Lesenswert?

TheBeginner schrieb:
> Danke für die Hilfe,
>
> hatte mich da verschriben mit "id_request". Und dem x habe ich die Länge
> des Strings zugewiesen.


Jetzt schreibst du 100 mal die Ergänzung zur Grundregel römisch 3 der 
Programmierung:

Ich soll meinen Variablen sinnvolle Namen geben!


x ist kein sinnvoller Name einer Variablen, die eine Stringlänge 
enthält.

von TheBeginner (Gast)


Lesenswert?

schaut jetzt alles folgendermaßen aus,
1
test_pointer=connection_establishment();
2
            string_length=strlen(test_pointer);
3
4
do
5
{
6
                  txbuf[tx_cnt]=test_pointer[tx_cnt];
7
tx_cnt++;
8
                  
9
}while(tx_cnt<string_length);
10
11
free(test_pointer);

Gruß

von TheBeginner (Gast)


Lesenswert?

wobei ich sagen muss, dass die Arrays den Speicher ungemein fressen.
Bei meinem Atmega acht komme ich langsam ins Schwitzen!

von Karl H. (kbuchegg)


Lesenswert?

TheBeginner schrieb:
> schaut jetzt alles folgendermaßen aus,
>
>
1
> 
2
> test_pointer=connection_establishment();
3
>             string_length=strlen(test_pointer);
4
> 
5
> do
6
> {
7
>                   txbuf[tx_cnt]=test_pointer[tx_cnt];
8
> tx_cnt++;
9
> 
10
> }while(tx_cnt<string_length);
11
> 
12
> free(test_pointer);
13
> 
14
>
>

so wärs einfacher/schneller (wenn auch nicht sicherer)
1
  test_pointer = connection_establishment();
2
  strcpy( txbuf, test_pointer );
3
  free( test_pointer );

benutz doch die Stringfunktionen! Dafür sind sie da, dass man nicht 
selber immer wieder Schleifen Konstrukte über Strings machen muss.

Aber wie gesagt (bzw. in der FAQ verlinkt): Eigentlich ist die ganze 
Idee der Rückgabe eines Strings aus einer Funktion indem man einen 
Buffer allokiert schon nicht besonders gut.

> wobei ich sagen muss, dass die Arrays den Speicher ungemein fressen.
> Bei meinem Atmega acht komme ich langsam ins Schwitzen!

Auf einem Mega8 möchtest du malloc eigentlich gar nicht benutzen.
Du solltest ernsthaft darüber nachdenken, Stringbuffer die du brauchst 
einmal zu allokieren und die dann in Funktionen hinein zu übergeben auf 
dass die Funktionen die Buffer gleich direkt befüllen anstatt 
haufenweise weiter Buffer zu allokieren. Dein Speicherverbrauch wird es 
dir danken, genauso wie die Laufzeit.

von Klaus W. (mfgkw)


Lesenswert?

TheBeginner schrieb:
> Bei meinem Atmega

Karl heinz Buchegger schrieb:
> Auf einem Mega8

Das Ganze in der Rubrik PC-Programmierung.

Und x kommt doch nirgends vor, oder bin ich blind?
Reden wir hier über abwesende Programme?

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> TheBeginner schrieb:
>> Bei meinem Atmega
>
> Karl heinz Buchegger schrieb:
>> Auf einem Mega8
>
> Das Ganze in der Rubrik PC-Programmierung.

Drum hab ich mich auch vorher nicht getraut, etwas zum malloc zu sagen 
:-)

>
> Und x kommt doch nirgends vor, oder bin ich blind?

Das hat er gelernt :-)
Er hat das x umbenannt auf string_length, was ja grundsätzlich gut ist.

Wollen wir nur hoffen, dass sein txt_cnt auch irgendwo auf 0 gesetzt 
wird :-) Sonst wartet schon der nächste Fehler, den er nicht hätte, wenn 
er einfach strcpy bzw. strncpy benutzen würde. Aber wem sag ich das. 
Manchmal ist es wirklich frustrierend.

von Klaus W. (mfgkw)


Lesenswert?

Also Standard-Tip:
Erst auf dem PC C lernen!
Das macht viel weniger Ärger (und immer noch genug) als auf einem MC.

Gibt es eigentlich schon die Standardantworten zum Anklicken
neben dem Textfeld hier?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.