getline in char

DarKo87

Mitglied
Moin,

Ich versuche gerade Zeilenweise aus einer Datei zu lesen.
Dies mache ich ganz einfach mit

Code:
while((line_val=getline(&line_ptr, t, datei)) != EOF)

Nun möchte ich jede Zeile in einen Char schreiben, damit ich diesen danach zerlegen kann.
Aber irgendwie möchte nichts klappen.

Kann mir vielleicht jemand ne hilfestellung geben?

Gruß DarKo
 
Hi.

So wie du das machst ist das grundlegend falsch. Das dürfte auch überhaupt nicht kompilieren, bzw. was für eine getline Funktion soll das denn sein?
C++:
while (::std::getline(datei, string)) {
}
Gruß
 
Code:
while((line_val=getline(line_ptr, t, datei)) != EOF)

Code:
size_t *t = malloc(0);
line_ptr = malloc(sizeof(char*));

Seh da eigentlich kein Problem bei mir, line_val gibt die zeilen länge ohne \n an.
ich brauche line_ptr keine länge anzugeben, weil es sich je nach länge der Zeile selbst
verlängert.
 
Aha, du hast dir also eine eigene getline Funktion geschrieben? Wie sieht die aus? Was ist line_ptr?

Und du verwendest C? Warum nimmst du dann nicht einfach fgets?
Code:
while((line_val=getline(line_ptr, t, datei)) != EOF)

Code:
size_t *t = malloc(0);
line_ptr = malloc(sizeof(char*));

Seh da eigentlich kein Problem bei mir
Dafür sehe ich welche...

sizeof(char*) ist immer konstant und ziemlich klein - die Größe eines Zeigers halt. Du solltest evtl. Speicher für einen String allozieren.

ich brauche line_ptr keine länge anzugeben, weil es sich je nach länge der Zeile selbst
verlängert.
Dann müßtest du aber die Adresse von line_ptr übergeben. Oder verwendest du doch C++ und Referenzen?

Zeig deinen Code.

Gruß
 
Okay mein Fehler, habe gerade gelesen wenn man getline(*ptr, *n, *stream) [*ptr = NULL, *n = NULL] übergibt die länge der Zeile übernimmt. Ich verwende C.

Meine Funktion soll ganz einfach die ausgelesene Zeile komplett in ein Char schreiben.
Damit ich diesen Char übergeben kann.


Code:
/********************* function definitions *******************************/
/***************************************************************************
* @NAME: t_read
* @FUNC: read all lines in open file*
*
***************************************************************************/

void *t_read (void){


	int8_t v_mutex, i;

	size_t *t = 0;
	line_ptr = NULL;

	v_mutex = pthread_mutex_lock(&dataMutex);
	while((line_val=getline(line_ptr, t, datei)) != EOF){
		//Send line to char
		pthread_cond_broadcast(&dataPresentCondition);
		pthread_cond_wait(&dataPresentCondition, &dataMutex);
	}

	pthread_mutex_unlock(&dataMutex);
	return 0;
}
 
Okay mein Fehler, habe gerade gelesen wenn man getline(*ptr, *n, *stream) [*ptr = NULL, *n = NULL] übergibt die länge der Zeile übernimmt.
Wie bitte?
Aha. Schau mal hier wie man die getline Funktion verwendet: http://linux.die.net/man/3/getline
Meine Funktion soll ganz einfach die ausgelesene Zeile komplett in ein Char schreiben.
Was ist Char? Ein typedef? Meintest du char? -> das wäre aber nur ein Zeichen...
 
Also die Funktion macht jetzt das was sie soll.
Jede Zeile wird komplett ausgelesen, egal wie lang sie ist.

In line_val steht die länge der Zeile.
Mit memcpy kann ich die komplette Line in den char kopieren der mit einer länge l[256] definiert wurde.

Is doch richtig oder? Weil Funktionieren tuts ;-)


Code:
char  **line_ptr;
char l[256];

void *t_read (void){
	
	int8_t v_mutex;

	size_t t = malloc(0);
	line_ptr = malloc(sizeof(char*));

	v_mutex = pthread_mutex_lock(&dataMutex);
	while((line_val=getline(line_ptr, t, datei)) != EOF){
		memcpy(&l, *line_ptr, 256);
		broadcast();
		pthread_cond_wait(&dataPresentCondition, &dataMutex);
	}

	pthread_mutex_unlock(&dataMutex);
	return 0;
}
 
In line_val steht die länge der Zeile.
Mit memcpy kann ich die komplette Line in den char kopieren der mit einer länge l[256] definiert wurde.
Du solltest nicht versuchen mehr Daten zu kopieren als vorhanden sind. In line_val steht die Länge der Zeile.
Is doch richtig oder?
Nein, nicht wirklich.

Warum schaust du dir denn nicht mal den Beispielcode an? Und achtest auf die Warnungen (-Wall einschalten!) des Compilers?

Gruß
 
Hi,

hier noch ein paar Voschläge von mir, wie ich das machen würde:

* v_mutex (zeile 7) brauchst du nicht, ausserdem liefert pthread_mutex_lock() laut doku einen int zurück, keinen int8_t.
* warum initialisiert du "t" mit malloc(0)? Würde auch den Namen von "t" anpassen, so dass das ganze mnemonischer wird.
* warum machst du nen pointer auf ein char*?
* weshalb ist deine Funktion mit einem Rückgabetyp "void*" deklariert, obwohl du nur "0" zurücklieferst?
* ich würde nur so viele Daten kopieren, wie auch gelesen wurden, also die Variable "t" (oder bei mir "len") verwenden.
* du allozierst für line_ptr Speicher, den du in der Funktion nicht mehr frei gibst. Speicherleck?

Hier mal mein Vorschlag, mit Kommentaren:
C:
#define INIT_BUFFER_SIZE 256
char* line = NULL;

int t_read(void) {
	/* zeile vorbereiten und Speicher reservieren */
	if(line == NULL) {
		line = (char*) malloc(sizeof(char) * INIT_BUFFER_SIZE);
		if(line == NULL) {
			errno = ENOMEM;
			return -1;
		}
	}
	
	/* länge des puffers speichern */
	size_t len = INIT_BUFFER_SIZE;

	/* mutex sperren */
	pthread_mutex_lock(&dataMutex);
	
	/* errno zurücksetzen */
	errno = 0;
	
	/* zeilenweise die daten lesen */
	while(getline(&line, &len, datei) != -1) {
		if(errno != 0) {
			/* fehler beim lesen, siehe doku von getline.
			 * wenn die funktion hier verlassen wird, sollte noch "line"
			 * per free() freigegeben werden */
		}

		/* broadscast */
		broadcast();
		
		/* pthread_cond_wait */
		pthread_cond_wait(&dataPresentCondition, &dataMutex);
	}
	
	/* mutex entsperren */
	pthread_mutex_unlock(&dataMutex);
	
	/* allozierten speicher freigeben */
	free(line);
	line = NULL;
	
	/* erfolg melden */
	return 0;
}

// Edit: Das ganze von mir ist ungetestet direkt aus meinem Kopf raus und hat noch keinen Compiler gesehen ;)

Gruß
BK
 
Zuletzt bearbeitet:
Danke erst einmal für die hilfe :) Ich bin noch in der Ausbildung und in der HMI hat leider nicht immer jeder Zeit für mich ;-) Aber fehler sind ja da um daraus zu lernen :-D

* v_mutex (zeile 7) brauchst du nicht, ausserdem liefert pthread_mutex_lock() laut doku einen int zurück, keinen int8_t.

Also v_mutex benutze ich damit ich den übergabe wert von mutex_lock prüfen kann.
Theoretisch könnte ich das dann so auch direkt an die Funktion übergeben.
Code:
c_value(pthread_mutex_lock(&dataMutex));

Code:
void c_value(uint16_t value){

	if(value==1){
		exit(1);
	}
}

Brauche also tatsächlich kein v_mutex.

* warum initialisiert du "t" mit malloc(0)? Würde auch den Namen von "t" anpassen, so dass das ganze mnemonischer wird.
* warum machst du nen pointer auf ein char*?

Ähm ja, also ich richte mich ein wenig nach dem Buch. C von A bis Z, ist nicht das beste, aber es hilft doch irgendwie. Kann also nicht ganz erklären warum der Autor das ganze auf malloc(0) setzt :-/ Aber malloc(0) ist ja eigentlich das gleiche wie NULL, oder?

Der Pointer auf char* ( so hab ich es verstanden ) erweitert sich selbst. Das bedeutet das es sich den Speicher nimmt was es braucht. Und char* ist ja 16 lang ... und durch den Pointer wird es immer wieder um 16 größer ... hmm, oder denk ich nun falsch?

* weshalb ist deine Funktion mit einem Rückgabetyp "void*" deklariert, obwohl du nur "0" zurücklieferst?

Das ist ganz einfach ... damit eclipse aufhört zu meckern! Ohne Return, gibt der mir meistens Warnings aus. Daher hau ich einfach nen return 0; unten dran. Stören tuts eigentlich nicht, weil nen rückgabe wert gibts ja auch eigentlich nicht, schlicht nur speicher verschwendung.

Das Programm steckt noch in den Kinderschuhen ;-) Ich hab die Funktionen noch nicht ganz ausgearbeitet, es fehlen ja auch noch die Fehler Meldungen. Die ich noch ausarbeiten muss.

Best regards DarKo87
 
Zuletzt bearbeitet:
Zurück