charmin
Elder0_o
|
hi, oc.at Bin wieder mal zu dumm. Bitte um Hilfe. Ich versteh nicht, warum ich meine einzelnen eingelesenen zeilen nicht in meine stringtabelle schön reinbring. Er speichert immer nur den letzten reinkopierten inputstring, ich möcht aber Zeile 1 in bigstring[1] drinhaben, zeile 2 in bigstring[2] usw, usf. Hätte mich daran orientiert: http://openbook.rheinwerk-verlag.de..._zeiger_009.htm/* ptrptr5.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *text[500];
char str1[] = "Text1";
char str2[] = "Text2";
char str3[] = "Text3";
text[0] = str1;
text[1] = str2;
text[2] = str3;
printf("%s %s %s\n", text[0], text[1], text[2]);
return EXIT_SUCCESS;
}
Nur dass ich meine einzelnen strings mit den einzeln eingelesenen Zeilen einer datei befüllen will. #include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <windows.h>
#define P 100
/***************************************************************************************************************/
/* DynamicText - Ein Programm, welches die Zeilen einer Datei in den Speicher einliest. Die Zeilen werden als */
/* String-Array gespeichert und das String-Array dynamisch verwaltet. Verwendet werden dazu die Funktionen */
/* malloc() und realloc(). Dadurch ist es möglich eine Datei in den Speicher zu laden, ohne vorher zu wissen */
/* wie groß diese Datei ist. */
/* Autor: */
/* Datum: 2016-03-05 */
/***************************************************************************************************************/
/****************************************************************/
/* Main Funktion */
/****************************************************************/
int main (int argc, char *argv[])
{
// Speichere alte Farben der Konsole
HANDLE h = GetStdHandle ( STD_OUTPUT_HANDLE );
WORD wOldColorAttrs;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
GetConsoleScreenBufferInfo(h, &csbiInfo);
wOldColorAttrs = csbiInfo.wAttributes;
/*************************/
/* Variablendeklaration */
/*************************/
// Einlesestring
char inputstring[P];
// String, welcher die ganze Eingabe speichert
char **bigstring;
// Größe des Strings für Speicherallozierung
int size=100;
//Filepointer
FILE *fp;
// Zählervariable für Zeilen
int k=0;
/*************************/
/* Ausgabe Programminfo */
/*************************/
// Ausgabe in der Farbe Rot
SetConsoleTextAttribute ( h, FOREGROUND_RED | FOREGROUND_INTENSITY );
printf("-----------------------------------------------------------------------------\n");
printf("| AnalyzeText - Ein Programm AnalyzeText, welches deine Datei zeichenweise |");
printf("\n| einliest. Das Programm sucht nach einem XML-Tag und gibt den Elementnamen |");
printf("\n| und gibt den Inhalt auf die Standardausgabe aus. |");
printf("\n| Version 1.0 |");
printf("\n| Autor: |");
printf("\n| Datum: 2016-03-05 |\n");
printf("-----------------------------------------------------------------------------\n\n");
// Ausgabe in Standardfarben
SetConsoleTextAttribute ( h, wOldColorAttrs);
// Bildschirmwechsel
system("PAUSE");
system("cls");
// Filesttream öffnen im "read only" Modus
fp=fopen("uebtext.txt", "r");
// Wenn Speicher nicht alloziert werden könnte, dann Fehlermeldung und Fehlercode 1 Rückmelden
if (!bigstring)
{
fprintf(stderr,"\nError");
return -1;
}
// Speicher allozieren für String
bigstring = (char *) calloc(size, sizeof(char));
printf("\n-----------------------------------------------------------------------------\n");
printf("| Lese Text aus Datei ein |\n");
printf("-----------------------------------------------------------------------------\n\n");
//Wenn fp 0 zurückliefert, also Datei unlesbar oder nicht auffindbar, dann Fehlermeldung
if (fp == NULL)
{
fprintf(stderr,"Datei kann nicht zum Lesen geoeffnet werden\n");
} else
{
int i=0;
// solange Fileende nicht erreicht, auslesen und ausgabe
while (fgets(inputstring,P,fp)!=NULL)
{
// Benötigter neuer Speicher
size += strlen(inputstring);
// Erweitere benötigten Speicher um die exakte Anzahl des eingelesenen Strings
bigstring = (char *) realloc(bigstring, size*sizeof(int));
// Wenn Speicher nicht alloziert werden könnte, dann Fehlermeldung und Fehlercode 1 Rückmelden
if (!inputstring)
{
fprintf(stderr,"\nError");
return -1;
}
// Zähler, wieviele Zeilen gelesen wurden
k++;
i++;
bigstring[i] = inputstring;
// Ausgabe
printf("%s",bigstring[i]);
}
}
printf("\nEs wurden %i Zeilen eingelesen\n",k);
printf("\n bigstring[1] = %s", bigstring[1]);
printf("\n bigstring[2] = %s", bigstring[2]);
printf("\n bigstring[3] = %s", bigstring[3]);
printf("\n bigstring[4] = %s", bigstring[4]);
printf("\n bigstring[5] = %s", bigstring[5]);
printf("\n bigstring[6] = %s", bigstring[6]);
printf("\n bigstring[7] = %s", bigstring[7]);
// Filestream schließen
fclose(fp);
// Speicher freigeben
free(inputstring);
printf("\n\n-----------------------------------------------------------------------------\n");
printf("| ENDE |\n");
printf("-----------------------------------------------------------------------------\n\n");
/*************************/
/* Programmende */
/*************************/
system("PAUSE");
return 0;
}
Ich checks nicht, warum ich nicht einfach die einzelnen zeilen abspeichern kann in meiner stringtabelle. bigstring[i] = inputstring;
// Ausgabe
printf("%s", bigstring[i]);
Ziel ist, dass ich über bigstring[1], bigstring[2], bigstring[3], ..... einfach auf meine einzelnen eingelesenen Zeilen hinzugreifen kann. tia!
Bearbeitet von charmin am 05.03.2016, 17:33
|
PuhBär
Schau ned so genau
|
InputString hat ja immer die gleiche Adresse. Du müsstest für jede eingelesene Zeile Memory allozieren und dann den Pointer in das Array schreiben.
Oder du kopierst direkt dir Adresse aus strdup von InputString.
Bearbeitet von PuhBär am 05.03.2016, 17:46
|
charmin
Elder0_o
|
ja stimmt, inputstring hat immer dieselbe Adresse und die Größe P.
Für jede Zeile Memory allozieren will ich ja, aber im bigstring, nicht im inputstring.
will quasi bigstring[1] mit dem aktuellen zeile im inputstring befüllen. Eine Runde weiter hat inputstring bereits den inhalt der nächsten Zeile statt der Ersten Zeile und die will ich dann in bigstring[2] reinkopieren.
ich will später eben die eingelesenen Zeilen einzeln aufrufen können mit bigstring[1...n]
|
PuhBär
Schau ned so genau
|
Deshalb musst du den Speicher ja auch kopieren, den du einliest, und nicht immer in InputString liegenlassen bzw. beim nächsten Mal überschreiben. Am Ende deines Programmes zeigen alle bigstring[i] auf den gleichen Speicher; deshalb siehst du immer nur die zuletzt eingelesene Zeile. Mit bigstring[i] = inputstring
kopierst du nichts; damit weist du nur die Adresse von inputstring einem Eintrag in deinem Array zu. Versuch mal bigstring[i] = strdup(inputstring)
Und du musst dann am Schluss noch einmal durch bigstring iterieren und free(bigstring[i])
aufrufen, sonst leakst du Speicher.
Bearbeitet von PuhBär am 05.03.2016, 18:09
|
charmin
Elder0_o
|
alles klar, probier ich dann gleich aus. danke schonmal  edit: wow, thx  haut jetzt hin. auf sowas wär ich nie gekommen, bzw erst nach zig stunden. hab an völlig falscher stelle gesucht jetzt und habs einfach nicht hingebracht. danke!
Bearbeitet von charmin am 05.03.2016, 18:25
|
11Fire01
Here to stay
|
da wünsche ich dir bei größeren programmen viel spaß
|
that
Hoffnungsloser Optimist
|
btw :scnr: i'd vote for sanders. y? take a look

Wieso "P"? Waren die sprechenden Namen schon aus?  // String, welcher die ganze Eingabe speichert
char **bigstring;
Das ist kein String, es ist ein Stringarray. // Größe des Strings für Speicherallozierung
int size=100;
Schon wieder 100? // Wenn Speicher nicht alloziert werden könnte, dann Fehlermeldung und Fehlercode 1 Rückmelden
if (!bigstring)
{
fprintf(stderr,"\nError");
return -1;
}
Abgesehen davon, dass dein Returnwert nicht mit dem Kommentar zusammenpasst, ist bigstring an dieser Stelle uninitialisiert. // Speicher allozieren für String
bigstring = (char *) calloc(size, sizeof(char));
Du musst dich entscheiden, ob bigstring ein String oder ein Stringarray sein soll. sizeof(char) ist konstant 1 - willst du hier Speicher für einen String mit 100 Zeichen oder Platz für 25 oder 12,5 Stringpointer anlegen? int i=0;
Was ist der Unterschied zwischen i und k? // Benötigter neuer Speicher
size += strlen(inputstring);
// Erweitere benötigten Speicher um die exakte Anzahl des eingelesenen Strings
bigstring = (char *) realloc(bigstring, size*sizeof(int));
Siehe oben - du musst dich entscheiden, ob du Platz für Stringpointer oder für die Inhalte anlegen willst. Wenn du die eingelesenen Strings mit strdup ins Array kopierst, brauchst du k * sizeof(char*) Bytes Speicher für die Pointer. // Wenn Speicher nicht alloziert werden könnte, dann Fehlermeldung und Fehlercode 1 Rückmelden
if (!inputstring)
{
fprintf(stderr,"\nError");
return -1;
}
inputstring ist ein Array, das kann nicht NULL sein. // Speicher freigeben
free(inputstring);
inputstring ist ein Array, das kannst du nicht mit free freigeben. Stattdessen willst du alle eingelesenen Strings in einer Schleife freigeben und dann das Array.
Bearbeitet von that am 05.03.2016, 20:53
|
charmin
Elder0_o
|
danke, dass du dir Zeit genommen hast!
|