frankx: Anfängerfrage zu Strings in C

Beitrag lesen

Hellihello

  
  
/***  
 * SplitLinesCsv  
 * splittet eine Textzeile am Komma auf,  
 * füllt die Teilzeichenketten in result  
 *  
 * @param line   Zeiger auf eine Zeichenkette  
 * @param result Zeiger auf ein Array von Zeichenketten  
 * @return       Anzahl der Teilzeichenketten  
 *  
 * Seiteneffekt: Speicher auf dem Heap wird allokiert  
 */  
int SplitLinesCsv(char* line, char** stringlist) {  
 printf("inputline: %s\n", line);  
    /* your code goes here */  
 #define SEPARATOR ','  
 #define LINEEND '\n'  
 int totalStringSize = strlen(line);  
 int seperatorCount = 0;  
  
 printf ("der Ausgangsstring hat %d Zeichen\n", totalStringSize);  
  
    // Ermittle, wieviele Teilzeichenketten es gibt  
 while (*line++ != '\0') {  
  if (*line == SEPARATOR)  
   seperatorCount++;  
 }  
 printf ("%d mal kam das Trennzeichen ('%c') vor\n",seperatorCount, SEPARATOR);  
  
 //reset Pointer  
 line -= totalStringSize+1;  
 printf("Pointerreset Test, inputline: %s\n", line);  
  
    // Allokiere den Speicher für das notwendige Array von Zeigern auf char  
 seperatorCount++; // eins mehr als Kommas vorhanden  
 printf ("alloziere Speicher für %d Zeiger auf Strings\n", seperatorCount);  
 stringlist[0] = (char*)malloc(seperatorCount*sizeof(int));  
    // Ermittle die Teilzeichenketten  
 int stringBufferCounter = 0;  
 char stringBuffer[totalStringSize];  
 int stringlistCounter = 0;  
  
    // Allokiere für jede Teilzeichenkette den notwendigen Speicher  
 while (*line != '\0') {  
  if (*line != SEPARATOR && *line != LINEEND) {  
   printf("puffere %c",*line);  
   stringBuffer[stringBufferCounter] = *line;  
   stringBufferCounter++;  
  }  
  else {  
   stringBuffer[stringBufferCounter++] = '\0';  
   printf("gepuffert wurde %s\n", stringBuffer);  
   printf("alloziere %d*%d Speicher für stringlist[%d]\n", stringBufferCounter, sizeof(char), stringlistCounter);  
   stringlist[stringlistCounter]=(char*)malloc(stringBufferCounter*sizeof(char));  
   printf("setze stringlist[%d]\n", stringlistCounter);  
   stringlist[stringlistCounter]=stringBuffer;  
   printf("gesetzt: %s\n", stringlist[stringlistCounter]);  
   printf("in speicher: %p\n", stringlist[stringlistCounter]);  
   stringBuffer[1] = '\0';  
   stringBufferCounter = 0;  
   stringlistCounter++;  
  }  
  *line++;  
 }  
  
    // ...  
 printf("pointer: %p\n",stringlist);  
 return seperatorCount;  
}  
  
int main() {  
 int cellcount, i;  
 char* line = "abcd,efgh,ijkl,mnop,qrst\n";  
 char** stringlist;  
 cellcount = SplitLinesCsv(line, stringlist);  
 printf ("\ntest aus main:\n\n");  
 printf("pointer strlinglist: %p\n", stringlist);  
 printf("pointer strlinglist[0]: %p\n", stringlist[0]);  
 printf("content strlinglist[0]: %s\n", stringlist[0]);  
  
 for(i=0; i<cellcount; i++) {  
  printf("testausgabe: %d\n", i);  
  printf("pointer: %p\n", stringlist[i]);  
 }  
}  
  

bringt als Ausgabe:

inputline: abcd,efgh,ijkl,mnop,qrst

der Ausgangsstring hat 25 Zeichen
4 mal kam das Trennzeichen (',') vor
Pointerreset Test, inputline: abcd,efgh,ijkl,mnop,qrst

alloziere Speicher für 5 Zeiger auf Strings
puffere apuffere bpuffere cpuffere dgepuffert wurde abcd
alloziere 5*1 Speicher für stringlist[0]
setze stringlist[0]
gesetzt: abcd
in speicher: 0x22cc50
puffere epuffere fpuffere gpuffere hgepuffert wurde efgh
alloziere 5*1 Speicher für stringlist[1]
setze stringlist[1]
gesetzt: efgh
in speicher: 0x22cc50
puffere ipuffere jpuffere kpuffere lgepuffert wurde ijkl
alloziere 5*1 Speicher für stringlist[2]
setze stringlist[2]
gesetzt: ijkl
in speicher: 0x22cc50
puffere mpuffere npuffere opuffere pgepuffert wurde mnop
alloziere 5*1 Speicher für stringlist[3]
setze stringlist[3]
gesetzt: mnop
in speicher: 0x22cc50
puffere qpuffere rpuffere spuffere tgepuffert wurde qrst
alloziere 5*1 Speicher für stringlist[4]
setze stringlist[4]
gesetzt: qrst
in speicher: 0x22cc50
pointer: 0x61141000

test aus main:

pointer strlinglist: 0x61141000
pointer strlinglist[0]: 0x22cc50
content strlinglist[0]: q
testausgabe: 0
pointer: 0x22cc50
testausgabe: 1
pointer: 0x22cc50
testausgabe: 2
pointer: 0x22cc50
testausgabe: 3
pointer: 0x22cc50
testausgabe: 4
pointer: 0x22cc50

"stringlist[stringlistCounter]=(char*)malloc(stringBufferCounter*sizeof(char));"
soll eigentlich jedem Element des String-Arrays einen weiteren freien Speicher zuordnen. Das ist aber immer die selbe Adresse.

Wie man sieht, bleibt der Pointer "hängen". Was mach ich falsch? Ich dachte schon, ich blick durch, aber jetzt kurz vor Schluss den Wald vor lauter Bäumen nicht.

Übrigens: In Zeile 58 "stringBuffer[1] = '\0'"; hatte ich zum Testen gesetzt, um die Ausgabe in Main nachvollziehen zu können (

printf("content strlinglist[0]: %s\n", stringlist[0]);

bring dann

" content strlinglist[0]: q"
).

Dank und Gruß,

frankx

--
tryin to multitain  - Globus = Planet != Welt