strtok & fscanf: reading from file

This is a discussion on strtok & fscanf: reading from file within the C Programming forums, part of the General Programming Boards category; Hi! New to these forums and I was hoping to seek help. I feel I'm going to be going here ...

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    5

    Thumbs up Answered: strtok & fscanf: reading from file

    Hi! New to these forums and I was hoping to seek help. I feel I'm going to be going here a lot so I'll post an introduction later. Anyway, on to my question.

    I'm writing code to read a file containing color names and color codes (separated by tab); for example:
    "Dark Purple\t8388736
    Black\t0
    Dark Blue/t160"

    I was able to read the color names by using strtok and then dynamically allocating memory for each color name, however I'm having trouble reading the ints into an array of ints. I don't know if it has to do with using strtok or if maybe it's a logical error?

    Here is part of my code:
    Code:
    if ( input != NULL ) {
    	 while (!feof(input)) {
    		fgets ( temp, MAX_TEMP, input );
    		str = strtok ( temp, "\t" );
    		*colors = allocateString(str);
    		fscanf( input,"[%*s %*s]\t%d", &tempNum );
    		codes[i] = tempNum;
    		printf( "%s\t%d\n", *colors, codes[i] ); // for debugging;
    		i++;
    		count++;
    		// read each line to a temp string then parse it
    	}
    	fclose(input);
    }
    This is what my output looks like:
    Enter a file name: p4 in.txt
    Red 0
    DARK Purple 0
    dark blue 0
    Yellow 0
    Black 0
    Forest Green 0
    Dark Blue 0
    Pastel Green 0
    Press any key to continue . . .
    Someone please help!
    Last edited by Ralph Cacho; 06-04-2011 at 06:37 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    fgets( buf, BUFSIZ, file );
    sscanf( buf, "%[^\t]\t%d", color, &number );
    I'd probably just do something like that. I'm not a fan of strtok. You could also squeeze a %n in there right after the first scan code and find out how many characters have been read if you really wanted to.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    5
    Quote Originally Posted by quzah View Post
    Code:
    fgets( buf, BUFSIZ, file );
    sscanf( buf, "%[^\t]\t%d", color, &number );
    I'd probably just do something like that. I'm not a fan of strtok. You could also squeeze a %n in there right after the first scan code and find out how many characters have been read if you really wanted to.


    Quzah.
    I've tried sscanf but unfortunately it gave me the same output with the color codes all printed as '0.' I'm also required to dynamically allocate memory for each of the color names, that's why I decided to use strtok. I'm not sure what I'm doing wrong..

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Make a small working example, not just a tiny fragment.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    int main( void )
    {
        FILE *fp = fopen( "yourfile.txt", "r" );
        if( fp )
        {
            char buf[ BUFSIZ ] = {0};
            size_t x = 0;
            
            for( x = 0; x < 5; x++ )
            {
                if( fgets( buf, BUFSIZ, fp ) )
                {
                    char colorname[ BUFSIZ ] = {0};
                    int colornumber = 0;
    
                    if( sscanf( buf, "%[^\t]\t%d", colorname, &colornumber ) == 2 )
                        printf( "name: \'%s\'\tnumber: %d\n", colorname, colornumber );
                    else
                        printf( "expected: NAME\\tNUMBER, got: %s\n", buf );
                }
            }
            fclose( fp );
        }
    
        return 0;
    }
    Looks about right, but I just rattled that off.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    5
    It worked! Thank you for pointing me in the right direction, quzah.
    I used sscanf before i used strtok and I was able to get the follow output (but it's printing the last color twice):

    Enter a file name: p4 in.txt
    DARK Purple 8388736
    dark blue 139
    Yellow 16776960
    Dark Blue 160
    Pastel Green 65280
    Pastel Green 65280
    Press any key to continue . . .
    Not sure why it's printing the last color twice.

    Code:
    int readFile ( char *colors[], int codes[] )
    {
    	FILE* input;
    	char fileName[MAX] = "";
    	char temp[MAX_TEMP] = "";
    	char *str;
    	int tempNum;
    	int count = 1;
    	int i = 0;
    
    	input = openFile( fileName, sizeof fileName );
    	
    	if ( input != NULL ) {
    		 while (!feof(input)) {
    			fgets ( temp, MAX_TEMP, input );
    			sscanf( temp, "%*[^\t]\t%d", &tempNum );
    			codes[i] = tempNum;
    			str = strtok ( temp, "\t" );
    			*colors = allocateString(str);
    			printf( "%s\t%d\n", *colors, codes[i] );
    			i++;
    			count++;
    			// read each line to a temp string then parse it
    		}
    		fclose(input);
    	}
    	return count;
    }
    Last edited by Ralph Cacho; 06-04-2011 at 02:57 AM.

  6. #6
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,705
    Quote Originally Posted by Ralph Cacho View Post
    It worked! Thank you for pointing me in the right direction, quzah.
    I used sscanf before i used strtok and I was able to get the follow output (but it's printing the last color twice):
    Not sure why it's printing the last color twice.
    You've made a mistake covered in the FAQ: Cprogramming.com FAQ > Why it's bad to use feof() to control a loop Basically what happens to you is, after the last good read, you execute the entire loop body again, which is not good. When fgets fails, it doesn't change the buffer you send it, so it will print it again, or whatever you do in the loop. Then after fgets has failed, the loop exits.

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    5
    Thanks for pointing me to the FAQ, whiteflags. It seems like it's a common mistakes for a beginner to make. Instead of a while, I used:

    Code:
    for ( i = 0; !feof(input); i++)
    It worked; but is it not recommended to do it that way?
    Last edited by Ralph Cacho; 06-04-2011 at 03:29 AM.

  8. #8
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,705
    Using a for loop, especially in that way, will not make feof() more correct. The FAQ that I linked you to does show you what code actually works, so I'm not sure what you misunderstand about that.

  9. #9
    Registered User
    Join Date
    Jun 2011
    Posts
    5
    What you said made sense and I read through the FAQ. I just wanted to check if it would be bad coding to use feof() in a for loop even though it worked. I realize now that doing it that way isn't guaranteed to work all the time. I ended up using the recommended method in the FAQ. Thanks again!
    Last edited by Ralph Cacho; 06-04-2011 at 04:05 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reading file with strtok
    By creilly in forum C Programming
    Replies: 6
    Last Post: 11-09-2010, 12:15 AM
  2. Reading file using fscanf into array
    By Sn0wcra5h in forum C Programming
    Replies: 3
    Last Post: 03-11-2010, 09:16 AM
  3. reading int and string from file fscanf
    By awesmesk8er in forum C Programming
    Replies: 5
    Last Post: 02-12-2009, 03:01 PM
  4. reading file and strtok
    By Butters007 in forum C Programming
    Replies: 7
    Last Post: 12-02-2006, 02:15 AM
  5. Ini File Reading using fscanf()
    By Mr.Modem in forum C Programming
    Replies: 5
    Last Post: 08-13-2005, 12:58 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21