Zum Inhalt springen

C - Variables string Array


Empfohlene Beiträge

Geschrieben

Hallo,

ich lese in meinem C Programm eine Datei zeilenweise ein per Funktion.

Jetzt möchte ich das ganze in einem Array speichern und zurückgeben an main.

Wie kann ich sowas den am besten realisieren?

bisher die Funktion zum einlesen der Datei:

void readFile(char *pFileName)

{

	FILE *pFile;

	char buffer[FILEROW];

	int i;


	pFile = fopen(pFileName,"r");

	if(pFile != NULL)

	{

		i = 0;

		while(fgets(buffer,FILEROW,pFile))

		{

			i++;

			printf("Zeile\t%i:\t%s",i,buffer);

		}

		fclose(pFile);

	}

}

Wie muss der Rückgabewert den sein?

Bzw. wie kann ich die Zeilen statt direkt auszugeben in ein Array speichern und zurückgeben mit return?

Gruß Scratch

Geschrieben

- zuerst schreibst du eine funktion, die die elemente deiner datei zählt

- in der main allokierst du den nötigen speicher des arrays

- speicherst den pointer in einer variablen p_x

- übergibst diesen Pointer auf das erste element des array

- fühlst den array

- und bist fertig

Geschrieben

Hi,

also danke erstmal für die Antworten.

Was haltet ihr von dieser Lösung:

int file_countRows(char *pFileName)
{
FILE *pFile;
char strBuffer[ROW];
int i;

// Open the file
pFile = fopen(pFileName,"r");
if(pFile == NULL)
{
return -1;
}

// Count the rows
i = 0;
while(fgets(strBuffer,ROW,pFile))
{
i++;
}
fclose(pFile);

return i;
}

char** file_read(char *pFileName)
{
FILE *pFile;
char strBuffer[ROW];

int i,j;
int iRows;

char **pArray;

// Count rows of the file
iRows = file_countRows(pFileName);
if(iRows < 0)
{
return NULL;
}

// Allocate space for the array rows
pArray = (char **) malloc(iRows * sizeof(char *));
if(pArray == NULL)
{
printf("Connat allocate enough virtual memory.\n");
return NULL;
}

// Allocate space for the array cols
for(i = 0;i < iRows;i++)
{
pArray[i] = (char *) malloc(ROW * sizeof(char));
if(pArray[i] == NULL)
{
printf("Connat allocate enough virtual memory for row %d\n",i);
return NULL;
}
}

// Open the file
pFile = fopen(pFileName,"r");
if(pFile == NULL)
{
printf("Connat open file");
return NULL;
}

// Fill the array
i = 0;
while(fgets(strBuffer,ROW,pFile))
{
strcpy(pArray[i],strBuffer);
i++;
}
fclose(pFile);

return pArray;
}[/PHP]

Vorlage hierfür war ein sehr gutes Beispiel von http://www.pronix.de/pronix-762.html

Gruß Scratch

Geschrieben
ich würde die Zeilen in der Datei nicht vorher zählen, sondern das array entsprechend erweitern.

das würde knallen, wenn du das zur laufzeit allokieren würdest. spätestens nach einem stark ausgelastetem Speicher eines Servers oder so. Das ist quick and dirty

Geschrieben
das würde knallen, wenn du das zur laufzeit allokieren würdest.
Wieso?

spätestens nach einem stark ausgelastetem Speicher eines Servers oder so.
Ich verstehe nicht, was du damit sagen willst :confused:

Das ist quick and dirty
Was genau jetzt? Dieser Ansatz? realloc an sich? Wenn du so überzeugt bist, dann bring doch mal ein paar Gründe für deine Behauptungen.
Geschrieben
Was haltet ihr von dieser Lösung:
Die casts auf den Rückgabewert von malloc sind unnötig und können Fehler verdecken. malloc gibt void* zurück, und der ist in jeden anderen Zeigertyp implizit konvertierbar, da braucht man keinen cast.
Geschrieben

Hallo,

das würde knallen, wenn du das zur laufzeit allokieren würdest. spätestens nach einem stark ausgelastetem Speicher eines Servers oder so. Das ist quick and dirty

Wieso das denn? Es ist wesentlich sinnvoller den Speicher während der Laufzeit zu besorgen, da man dann nur das reservieren muss was auch benötigt wird.

Nic

Geschrieben

vielleicht habe ich die Speicherverwaltung auch falsch verstanden, aber ist es nicht so, dass nach meinem Vorschlag das System schaut wo finde ich ein geeignetes Plätzchen für mein Array der Länge X, die ich ja kenne und dass nach dem anderen Verfahren, das System irgendwo das erste Element des Arrays setzt und genau von hier an, diesen Array um X - Byte, was ja hier nicht bekannt ist, erweitert ?

Das Problem welches ich sehe ist folgendes:

1) man weiss in der Regel nicht wie viele Elemente in der Datei sind

2) malloc immer nur den nächsten Speicherblock nimmt

3) wenn die Datei sehr lang ist, er ggf. auf andere, sich im Speicher befindlichen Elemente, stößt und sie überschreibt oder nicht weiter macht wegen Zugriffsverletzung

Liege ich hier falsch ? Wenn ja, erbitte ich einen Link wo ich das vorgehen von Malloc und die tatsächliche Speicherverwaltung nachlesen kann.

Geschrieben

Ja da liegst du falsch wenn es so wäre dann wäre es ja grausam und du könntest nicht viel mit deinem PC anfangen ;)

malloc kuckt natürlich nach ob an der Stelle wo es reserviert genug Platz für alle Daten ist, wenn nicht sucht es eine andere Stelle und wenn es keine findet dann gibt es NULL zurück.

Wenn du diesen speicher nun zur Laufzeit erweitern willst und an der Stelle ist nicht genug Platz dann wird er automatisch von realloc an eine Stelle verschoben wo genug Platz dafür ist.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_CRT_malloc.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_realloc.asp

Noch ein kleiner Tipp wenn man eh mit realloc arbeiten will kann man sich das malloc sparen. realloc mit NULL als erstem Parameter arbeitet wie malloc. Das eigenet sich somit gut für Schleifen.

Geschrieben
1) man weiss in der Regel nicht wie viele Elemente in der Datei sind
Richtig. Deshalb aber vorher zu zählen, ist ineffizient und unnötig.

2) malloc immer nur den nächsten Speicherblock nimmt
Der Begriff "nächster" Speicherblock ist ungünstig gewählt. Unterhalb von malloc liegt das Speichermanagement des Betriebssystems. Das kann mit deinem Speicher machen was es will. Es muss nicht sein, dass zwei Elemente eines Arrays in C im physischen Speicher nebeneinander liegen. Es kann sein, dass sie überhaupt nicht im RAM liegen. Du sorgst dich da um Dinge, auf die du sowieso keinen Einfluss hast, zumindest wenn du ein heute aktuelles Betriebssystem benutzt, um deine Programme auszuführen.

3) wenn die Datei sehr lang ist, er ggf. auf andere, sich im Speicher befindlichen Elemente, stößt und sie überschreibt oder nicht weiter macht wegen Zugriffsverletzung
Nein, dafür gibt es realloc. Damit kann man ein Array einfach zur Laufzeit vergrößern. Und da es sich nur um ein Array von Zeigern handelt, ist das nicht einmal besonders aufwändig.
Geschrieben
Zitat von Klotzkopp Die casts auf den Rückgabewert von malloc sind unnötig und können Fehler verdecken. malloc gibt void* zurück, und der ist in jeden anderen Zeigertyp implizit konvertierbar, da braucht man keinen cast.

Lasse ich den cast weg kommt:

cannot convert `void *' to `char *' in assignment

Compiler ist gcc.

Gruß Scratch

Geschrieben

Ok, daran lags ;-)

Jetzt hab ich aber noch eine Frage über realloc

astrFile = NULL;
a = 0;
while(!file.eof())
{
getline(file,strLine);
a++;
astrFile = (string *) realloc(astrFile,a * sizeof(string));
astrFile[a].assign(strLine);
}
file.close();[/PHP]

ergibt: "Segmentation fault"

Kann es daran liegen das sizeof(string) variabel ist, je nach Länge des Strings?

Oder gibt es in C++ vielleicht noch eine viel bessere Lösung für sowas mit vektor oder queue?

Geschrieben

Die Speicherfunktionen von C darfst du für Klassen nicht benutzen, weil sie keine Konstruktoren oder Destruktoren aufrufen können. Die können nur den Speicherinhalt kopieren, was bei Klassen, die dynamisch Speicher anfordern, zwangsläufig zu Problemen führt.

Wenn du aber sowieso C++ benutzt, brauchst du gar kein realloc, denn dafür gibt es in C++ die Container der Standardbibliothek:

vector<string> v;
while(getline(file, line))
{
v.push_back(line);
}[/code]

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...