-
seperate function
I am trying to read from a file that looks like this
Code:
Joseph Stevens Boys 11 20 5
Jamie Stevens Girls 22 18 6
Tony Waters Boys 33 22 7
Sally Smith Girls 44 33 8
when I read from this file I want to store each of these values in a string or int. Then I want to output to files called east and west, in this format:
Lastname Firstname Teamname Scoring average
Code:
tokstring ( )
{
FILE * input, * east, * west;
char string;
char *token;
char *first;
char *last;
char *team;
int *number;
int *points;
int *games;
double *average;
while ( first || last || team || number || points || games != NULL )
{
fgets (string, 80, input );
first = strtok (NULL, " ");
last = strtok (NULL, " ");
team = strtok (NULL, " ");
number = strtok (NULL, " ");
points = strtok (NULL, " ");
games = strtok (NULL, " ");
fprintf (east, "%s\t", last);
fprintf (west, "%s\t", last);
fprintf (east, "%s\t", first);
fprintf (west, "%s\t", first);
if ( team == "girls" );
fprintf (east, "%s\t", team);
else
fprintf (west, "%s\t", team);
average = ( points / games );
fprintf (east, "%6.2f\t", average);
fprintf (west, "%6.2f\t", average);
}
}
}[/CODE]
the error messages I get when I compile are
Code:
project8.c: In function `tokstring':
project8.c:68: `input' undeclared (first use in this function)
project8.c:68: (Each undeclared identifier is reported only once
project8.c:68: for each function it appears in.)
project8.c:68: warning: passing arg 1 of `fgets' makes pointer from integer without a cast
project8.c:72: warning: assignment from incompatible pointer type
project8.c:73: warning: assignment from incompatible pointer type
project8.c:74: warning: assignment from incompatible pointer type
project8.c:76: `east' undeclared (first use in this function)
project8.c:77: `west' undeclared (first use in this function)
project8.c:82: parse error before `else'
project8.c:84: invalid operands to binary /
-
Yeah if you look carefully at the code you posted
> fgets (string, 80, input );
you'll notice stuff like this. Is string really a file, and if so where have you defined it? There is no character array input defined in this function either.
I think you're confused about what strtok returns. It returns a character array, not a letter or an int or something else.
> first = strtok (NULL, " ");
> last = strtok (NULL, " ");
> team = strtok (NULL, " ");
None of these make any sense because strtok expects a delimiter to be an ASCII character not a string.
As usual, the one-two punch of fgets and sscanf would work nicely here.
-
Ok, I declared string, and I added *'s in the declarations. I will update post and errors.
-
forgot,
FILE * input, * east, * west;
updating post now
-
project8.c: In function `tokstring':
project8.c:68: `input' undeclared (first use in this function)
input once again is not a character array. You are confused about the arguments of fgets apparently. The stream to read is the first argument, then comes the number of characters to read, then the string to store it all in. Since input is defined as a char *, you will get an error like this one, and probably lots of unexpected type conversions.
project8.c:68: (Each undeclared identifier is reported only once
project8.c:68: for each function it appears in.)
project8.c:68: warning: passing arg 1 of `fgets' makes pointer from integer without a cast
string is a character, not a FILE * like what was expected.
project8.c:72: warning: assignment from incompatible pointer type
project8.c:73: warning: assignment from incompatible pointer type
project8.c:74: warning: assignment from incompatible pointer type
strtok returns a character array. No exceptions.
project8.c:76: `east' undeclared (first use in this function)
project8.c:77: `west' undeclared (first use in this function)
project8.c:82: parse error before `else'
> if ( team == "girls" );
Not to mention that even if this did parse correctly, it doesn't do what you think it does. What actually happens is a pointer comparison, not a lexicographical comparison (seeing if two strings contain something different) and string literals never compare equally with character arrays. You want to use strcmp here.
project8.c:84: invalid operands to binary /
There is no such thing as pointer division.
To fix all these errors, maybe you could at least use fscanf ? I'd preferyou use fgets and sscanf, but I think you need to practice reading the actual file first before doing anything better. Next time you update your code, resist the temptation to use pointers. You need to read actual integers and actual character arrays. I highly doubt that you need to use strtok at all, not to mention that you use it incorrectly, but not quite the same way I said so.
Topics you ought to read include:
-
Code:
tokstring ( void )
{
FILE * input, * east, * west;
char string [ 80 ];
char token;
char first;
char last;
char team;
int number;
int points;
int games;
double average;
first = *strtok( string, " " );
while ( first || last || team || number || points || games != NULL )
{
fgets (string, 80, input );
first = *strtok (NULL, " ");
last = *strtok (NULL, " ");
team = *strtok (NULL, " ");
number = *strtok (NULL, " ");
points = *strtok (NULL, " ");
games = *strtok (NULL, " ");
fprintf (east, "%s\t", last);
fprintf (west, "%s\t", last);
fprintf (east, "%s\t", first);
fprintf (west, "%s\t", first);
fprintf (east, "%s\t", team);
fprintf (west, "%s\t", team);
average = ( points - games );
fprintf (east, "%6.2f\t", average);
fprintf (west, "%6.2f\t", average);
}
return ( 0 );
}
compiling works, but when I run the program I get
-
if you do not get any warnings - change your compiler
you are using alot of not-initialized vars
your format in printf does not correlates with your var types
you dereference return values of strtok without checking if it is not null
your conversion from char to int is wrong
-
you would be suprised on how that does not help.
-
> first = *strtok (NULL, " ");
What is it that you are trying to do here? Don't hack your program until you can fit whatever you need into a character. I've told you already that strtok returns a chacter array. And you can only pass it a NULL argument after you've parsed a buffer at least once.
Why are you working so hard to parse input anyway? fgets and sscanf can pretty much take care of what you need to do.
Code:
#include <stdio.h>
struct player_t {
char first[32];
char last[32];
char team[32];
int number;
int points;
int games;
};
int main( void )
{
struct player_t player;
char line[BUFSIZ] = "deadbeef\n";
FILE *fin, *fout;
if( (fout = fopen( "example.txt", "w" )) != NULL )
{
int written = 0;
written += fprintf( fout, "Joseph Stevens Boys 11 20 5\n" );
written += fprintf( fout, "Jamie Stevens Girls 22 18 6\n" );
written += fprintf( fout, "Tony Waters Boys 33 22 7\n" );
written += fprintf( fout, "Sally Smith Girls 44 33 8\n" );
printf( "%d bytes written to file\n\n", written );
fclose( fout );
}
else
{
printf( "Couldn't write input file, buy a bigger hard drive\n" );
return 0;
}
if( (fin = fopen( "example.txt", "r" )) != NULL )
{
int linecount = 0;
while( fgets( line, sizeof line, fin ) != NULL )
{
int read = sscanf( line, "%32s %32s %32s %d %d %d",
player.first, player.last, player.team, &player.number, &player.points, &player.games );
if( read == 6 )
{
printf( "\"%s %s\" number %d of team \"%s\" has scored %d points in %d games.\n",
player.first, player.last, player.number, player.team, player.points, player.games );
}
else
{
printf( "Error in line %d. Only %d items read successfully.\n", linecount, read );
printf( "Trying to read rest of file...\n" );
continue;
}
linecount++;
}
}
fclose( fin );
printf( "\nAttempt to remove file was %s\n", remove( "example.txt" )? "not successful" : "successful" );
return 0;
}
My thanks goes to Quzah -- I had to try it just once.