Was ist falsch (strtok)
-
Hallo
Ich möchte aus einer Datei die verschieden Groß ist und folgendermassen aussieht den Wert vor dem ; und danach je in ein Array speichern:**
Text0;0000000
Text1;0100001
Text2;0200002
Text3;0300003
Text4;0400004
Text5;0500005
**#include <stdio.h> #include <string.h> #include <stdlib.h> int main (void) { FILE * pFile; char **pointer; char *bigbuffer; char *teiler; int i=0,j,k; long size; pFile = fopen ("test.txt","r"); if (pFile!=NULL) { fseek(pFile,0,SEEK_END); size=ftell(pFile); rewind(pFile); bigbuffer=(char*) malloc(size); fread(bigbuffer,1,size,pFile); teiler=strtok(bigbuffer,";"); while(teiler!=NULL) { pointer[i]=(char*) malloc(strlen(teiler)+1); if (pointer[i]==NULL) { printf("KEIN SPEICHER"); break; } strncpy(pointer[i],teiler,strlen(teiler)+1); teiler=strtok(NULL,";\n"); printf("Pointer %d: %s\n",i,pointer[i]); i++; } fclose (pFile); } for(j=0;j<i;j++){ printf("(Ausserhalb) Pointer %d: %s\tGroesse=%d\n",j,pointer[j],strlen(pointer[j])); //TEST } for(k=i;k>=0;i--) { free(pointer[i]); } free(bigbuffer); return EXIT_SUCCESS; }
Wenn ich nur 2 Zeilen in meiner Datei habe funktioniert es ohne Fehler; sonst nicht.
lg Maxx
-
Maxx175 schrieb:
/* bigbuffer = ( char* )malloc( size ); ^ Siehe Signatur ^^ */ bigbuffer = malloc( size + 1 ); /* abschließendes '\0' berücksichtigen und */ if( !bigbuffer ) { /* auf Erfolg prüfen. */ puts( "Not enough Memory!\n" ); fclose( pFile ); return EXIT_FAILURE; }
Maxx175 schrieb:
/* fread( bigbuffer, 1, size, pFile ); logisch wär's eher andersrum... */ if( !fread( bigbuffer, size, 1, pFile ) ) { /* und auf Erfolg prüfen */ puts( "Data couldn't be read!\n" ); free( bigbuffer ); fclose( pFile ); return EXIT_FAILURE; } /* und den String abschließen: */ bigbuffer[ size ] = '\0';
Maxx175 schrieb:
teiler = strtok( bigbuffer, ";" ); while( teiler != NULL ) { pointer[ i ] = ( char* ) malloc( strlen( teiler ) + 1 ); /* ^ Hier beginnen Deine Probleme, da du versuchst Speicher für einen Pointer des Pointer-Arrays 'pointer' anzufordern, das das selbst noch auf Datenmüll (*pointer) zeigt. */
Du müsstest also die Anzahl der Zeilen in
test.txt
kennen, um ausreichend Speicher für*pointer
anfordern zu können.Weiters halte ich es für günstiger, die Daten nicht ständig doppelt im Speicher zu halten, sondern nur die, die man auch wirklich benötigt. So zB:
#include <stdlib.h> #include <string.h> #include <stdio.h> char* read_line( FILE *file ) { char *line = malloc( 1 ); char *tmp = 0; size_t line_length = 1; int ch = 0; if( file && line ) { while( ( ( ch = fgetc( file ) ) != EOF ) && ( ch != '\n' ) ) { line[ line_length - 1 ] = ch; if( !( tmp = realloc( line, ++line_length ) ) ) { free( line ); return 0; } line = tmp; } line[ line_length - 1 ] = '\0'; } return line; } int main( void ) { const char input_file_name[ ] = "test.txt"; FILE *input_file = fopen( input_file_name, "r" ); char *line_buffer = 0; size_t token_count = 0; char **data = 0; char **tmp = 0; char *token = 0; size_t i = 0; if( !input_file ) { fprintf( stderr, "File \"%s\" couldn't be opened for reading!\n\n", input_file_name ); return EXIT_FAILURE; } while( !feof( input_file ) && ( line_buffer = read_line( input_file ) ) && ( line_buffer[ 0 ] ) ) { if( !( tmp = realloc( data, ( token_count += 2 ) * sizeof( char* ) ) ) ) { fputs( "Not enough memory!\n\n", stderr ); free( line_buffer ); free( data ); fclose( input_file ); return EXIT_FAILURE; } data = tmp; if( !( data[ token_count - 2 ] = malloc( strlen( token = strtok( line_buffer, ";" ) ) + 1 ) ) ) { fputs( "Not enough memory!\n\n", stderr ); free( line_buffer ); free( data ); fclose( input_file ); return EXIT_FAILURE; } strcpy( data[ token_count - 2 ], token ); if( !( data[ token_count - 1 ] = malloc( strlen( token = strtok( 0, ";" ) ) + 1 ) ) ) { fputs( "Not enough memory!\n\n", stderr ); free( line_buffer ); free( data ); fclose( input_file ); return EXIT_FAILURE; } strcpy( data[ token_count - 1 ], token ); free( line_buffer ); } for( ; i < token_count; ++i ) { puts( data[ i ] ); } for( i = 0; i < token_count; ++i ) { free( data[ i ] ); } free( data ); fclose( input_file ); }
cheers, Swordfish
PS: Wenn die Datei das vorgegebene Format mit zwei Token pro Zeile nicht einhält, fliegt Dir mein Code natürlich um die Ohren.
-
Super Dein Code klappt einwandfrei.
Danke für die Hilfe
lg Maxx175