WCM Forum

WCM Forum (http://www.wcm.at/forum/index.php)
-   Programmierung (http://www.wcm.at/forum/forumdisplay.php?f=17)
-   -   C - char* und char[] (http://www.wcm.at/forum/showthread.php?t=112596)

K@sperl 18.10.2003 22:00

C - char* und char[]
 
Hab da ein kleines C Problem, folgende Problemstellung:
Das Programm soll aus zwei Arrays(consonants, vowels) jeweils einen Buchstaben auslesen, wobei der Buchstabe per Zufallszahl ausgewählt wurde, und diesen Buchstaben dann in einen String str einfügen. Da die Funktion, die das bewerkstelligt, aber vom Datentyp char* ist, und der String, der aus den einzelnen Buchstaben zusammengesetzt ist vom Datentyp char, passt das natürlich nicht. Drum hab ich mir gedacht, daß ich den fertigen String str mit einem impliziten Typecast durch Zuweisung an brand vom Datentyü char* ebenfalls zu char* konvertieren kann und diesen dann an die Funktion NewBrand zurückgebe - geht aber nicht, keine Ahnung warum, da wir noch nicht gelernt haben was char* ist, und ich aufgrund einer Mathe Klausur auch nicht genug Zeit habe mir das alles selbst rauszusuchen. Aja, als Kommandozeilenparameter wird die Länge des Strings mitgegeben, hier im Programm als Var. n


Hier ist mal der Code der entsprechenden Funktion
Code:

char* NewBrand(int n) {
  int cons, vow, i;
  char str[n];
  char* brand;
  i = 0;
  while(i < n) {
    cons = RandNumber(21);
    vow = RandNumber(5);
    str[i] = consonants[cons];
    i = i + 1;
    if(i < n) {
      str[i] = vowels[vow];
      i = i + 1;
    }
  }
  brand = str;
  //printf("%s", str);
  //printf("%d", i);
  return brand;
}


sagi 18.10.2003 23:32

Nachdem du von brand nur die Adresse uebergibst solltest du IMHO den Speicher schon vorher alliziieren.

nach
PHP-Code:

charbrand

machst du ein

PHP-Code:

brand = (char *)malloc(sizeof(char)); 

evtl. poste bitte die Fehlermeldung.

mfg

c.

sagi 19.10.2003 01:13

Sorry. ich hab da was uebersehen. wenn du in brand mehrere Zeichen speicherst musst du das natuerlich beim malloc beruecksichtigen:

PHP-Code:

malloc(2*sizeof(char)) 

alloziiert dir Speicher fuer 2 Chars.

In deinem Fall:

PHP-Code:

brand = (char *)malloc(n*sizeof(char)); 

mfg
c.

K@sperl 19.10.2003 23:40

Geht leider noch immer nicht.

Wenn ich aber innerhalb der Funktion NewBrand 'brand' ausgebe, wird es korrekt ausgegeben, wenn ich aber 'brand' an main zurückgebe, und dann in main die entsprechende Var. ausgebe, sehe ich nur Sonderzeichen.

Biri 19.10.2003 23:54

Zitat:

Wenn ich aber innerhalb der Funktion NewBrand 'brand' ausgebe, wird es korrekt ausgegeben, wenn ich aber 'brand' an main zurückgebe, und dann in main die entsprechende Var. ausgebe, sehe ich nur Sonderzeichen.
Das liegt daran, dass du einen zeiger auf eine stack-variable zurückgibts. Darf man nicht machen, da dieser anch dem Verlassen der Fu. nicht mehr gültig ist.
Korrekte Vorgangsweise: Speicher am Heap allokieren oder Speicher für string in der main funktion vereinbaren + zeiger auf diesen der Fu. übergeben.

fg
-hannes

K@sperl 20.10.2003 00:06

Da ich von Zeigern, zumindest in C, noch keine Ahnung hab, bitte ich dich mir das genauer zu erklären.

sagi 20.10.2003 00:09

Ok. ich habs mir noch mal genauer durchgesehen... ich sollte wirklich gruendlicher schauen :)

den malloc fuer brand kannst du vergessen, da du ja hier:
PHP-Code:

brand str

nicht die Daten sondern die Adresse uebergibst. Das Problem dabei ist, dass dieser Speicherbereich mit dem Ende der Funktion geloescht wird und daher der Pointer ins nichts geht.

Mir stellt sich allerdings die Frage, ob du nicht einfach auf die Variable "str" verzichten kannst und gleich mit brand arbeiten kannst?

PHP-Code:

charNewBrand(int n) {
  
int consvowi;
  
charbrand;
  
brand = (char *)malloc(sizeof(char)+1);
  
0;
  while(
n) {
    
cons RandNumber(21);
    
vow RandNumber(5);
    
strncat(brand, &consonants[cons], 1);
    
1;
    if(
n) {
      
strncat(brand, &vowels[vow], 1);
      
1;
    }
  }
  return 
brand;


hab das aber nicht getestet. Du musst natuerlich die string.h verwenden.

mfg
c.

K@sperl 20.10.2003 00:19

@sagi

So in der Art hatte ich es, schon aber ich hab das & bevor ich den char aus dem Array auslese nicht gemacht, kann das vielleicht damit zusammenhängen, daß es nicht funktioniert hat?
Was macht dieses '&' eigentlich?


edit: das '&' zeigt anscheinend auf die Adresse des jeweiligen Elements, stimmt das? Falls ja, würde ja brand immer auf ein anderes Element zeigen, und nicht auf den gesamten String brand?

sagi 20.10.2003 00:28

das & gibt die Adresse an. Wenn du das nicht gemacht hast, dann ist das sicherlich der Grund.

auch wenn in der Funktion die Adressen uebergeben werden, werden die Inhalte kopiert. die Adresse von brand aendert sich daher nicht.

mfg
c.

[edit]
Falls du eine gute Doku dazu brauchst:
http://www.pronix.de/C/standard_C/c_...ung_14_3.shtml

K@sperl 20.10.2003 00:31

Danke, ich les grad C programming language, absolut spitzen Lektüre :)

_m3 20.10.2003 10:05

Zitat:

Original geschrieben von sagi
Das Problem dabei ist, dass dieser Speicherbereich mit dem Ende der Funktion geloescht wird und daher der Pointer ins nichts geht.
Wie waers mit "static"?
Zitat:

Der Modifier static erzeugt dauerhaften Speicher fuer eine Variable. Das heisst der Wert einer funktionslokalen Variablen bleibt erhalten und beim naechsten Aufruf kann wieder drauf zugegriffen werden.

sagi 20.10.2003 11:32

m3: das ist einfach unschoener Programierstil ;).

1) Der Quelltext wird dabei unuebersichtlich.

2) Abgesehen davon ist es auch nicht sehr gut, wenn das Ding die ganze Zeit im Speicher herumliegt. Braucht ja alles seinen Platz.

Also auch wenn dieser Weg wesentlich einfacher ist ist unbedingt davon abzuraten.

mfg

c.

_m3 20.10.2003 13:59

War ja nur ein Vorschlag. ;)
Wahre Männer machen das alles mit malloc! :cool:

sagi 20.10.2003 14:21

Zitat:

Wahre Männer machen das alles mit malloc!
eben ;)

Wahre Maenner wuerden das aber auch mittels Rekursoin machen... nicht etwa, weil es schneller oder einfacher ist... nein, weil sie es koennen :D

mfg

c.

_m3 20.10.2003 14:30

Gibt es andere Lösungsmöglichkeiten als eine Rekursion? ;)

Biri 20.10.2003 14:44

was ist überhaupt der sinn dieses sources ?
zeichenketten mit zufälliger abfolge von selbst- u. mitlauten erzeugen ? (wozu braucht ma das ?)

PHP-Code:

charNewBrand(int n) { 
  
int consvowi
  
charbrand
  
brand = (char *)malloc(sizeof(char)+1); 
  
0
  while(
n) { 
    
cons RandNumber(21); 
    
vow RandNumber(5); 
    
strncat(brand, &consonants[cons], 1); 
    
1
    if(
n) { 
      
strncat(brand, &vowels[vow], 1); 
      
1
    } 
  } 
  return 
brand


- für brand werden 2 zeichen allokiert - bissl wenig, oder ?
- wozu das "if" - die angegebene bedingung ist immer true ! (weil in schleife)

-hannes

sagi 20.10.2003 15:04

Zitat:

Original geschrieben von Biri
was ist überhaupt der sinn dieses sources ?
zeichenketten mit zufälliger abfolge von selbst- u. mitlauten erzeugen ? (wozu braucht ma das ?)

- für brand werden 2 zeichen allokiert - bissl wenig, oder ?
- wozu das "if" - die angegebene bedingung ist immer true ! (weil in schleife)

-hannes

1) muss natuerlich
PHP-Code:

brand = (char *)malloc(n*sizeof(char)+1); 

heissen :)

2) nein. davor ist ja ein i = i + 1; (btw: ++i ist einfacher :) )

@m3: :confused: angeblich. ich hab mich auch gewundert

mfg
c.

Biri 20.10.2003 17:56

Zitat:

2) nein. davor ist ja ein i = i + 1; (btw: ++i ist einfacher )
stimmt - das hab ich übersehn. ;)

-hannes

_m3 20.10.2003 18:00

Zitat:

Original geschrieben von sagi
2) nein. davor ist ja ein i = i + 1; (btw: ++i ist einfacher :) )
WURSCHT! Das optimiert ein aktueller Compiler eh.

sagi 20.10.2003 18:10

Zitat:

Original geschrieben von _m3
WURSCHT! Das optimiert ein aktueller Compiler eh.
Im Prinzip ist es egal. Es geht nur darum, dass man "sauberen Code" hat.

mfg

c.

irrsinn 21.10.2003 10:37

Zitat:

Gibt es andere Lösungsmöglichkeiten als eine Rekursion?
diesen herbst sind die jump anweisungen wieder in mode! :D


Alle Zeitangaben in WEZ +2. Es ist jetzt 03:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag