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


Anmelden zum Antworten