C: Reading strings from binary file - c

I have a home assignment which says that I have to store information about a mansion in a binary file. On the first line of that file I have to keep information about how many floors there are in the building and how many apartments there are on a floor (size of two-dimensional array). And on the next lines I have to keep info about the apartments - a unique number for each apartment, number of rooms in that apartment, number of people living there, family name, date when the family moved in that apartment, monthly rent.
So, the question is: how should I store that information and how should I read it? If I use fread(buf, size, number_of_elements, FIlE *), how would I know the number of the elements?
For example, how do I read a family name when I don't know it's lenght?
Thanks in advance!
PS. Thank you, claptrap! I tried to write the data first into the binary file but I got some error :(
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define NAPARTMENTS 21
#define TAX_ADULT 3
#define TAX_KID 1
#define TAX_ELEVATOR 2
#define NFLOORS 7
#define NROOMS 3
void main()
{
FILE *fp;
int i, j;
struct info_apartments
{
unsigned numApartment, numRooms, numAdults, numKids, rent;
char family[30], date[10];
};
typedef struct info_apartments data;
data apartments[7][3];
for(i=0; i<NFLOORS; i++)
for(j=0; j<NROOMS; j++)
{
apartments[i][j].numApartment=i*10+j+1;
printf("\nEnter the number of the rooms: ");
scanf("%d", apartments[i][j].numRooms);
printf("\nEnter number of adults: ");
scanf("%d", apartments[i][j].numAdults);
printf("\nEnter number of kids: ");
scanf("%d", apartments[i][j].numKids);
printf("\nEnter family name: ");
scanf("%s", apartments[i][j].family);
printf("\nEnter date: ");
scanf("%s", apartments[i][j].date);
//first two floors don't pay for elevator
if(i+1<3)
apartments[i][j].rent=(TAX_ADULT*apartments[i][j].numAdults)+(TAX_KID*apartments[i][j].numKids);
else
apartments[i][j].rent=((TAX_ADULT+TAX_ELEVATOR)*apartments[i][j].numAdults)+((TAX_KID+TAX_ELEVATOR)*apartments[i][j].rent);
}
if((fp=fopen("myfile", "ab"))==NULL)
{
printf("Error");
exit(1);
}
if((fwrite(apartments, sizeof(apartments), 1, fp))!=1)
{
printf("Error!\n");
exit(1);
}
}

First of all I guess you need to change the "if" line at the end to:
if((fwrite(&apartments, sizeof(apartments), 1, fp))!=1)
You forgot to put &..
second... if you want to
read from the file you do the same thing with fread function
fread(&apartments, sizeof(apartments), 1, fp);
and the you can print it so you can see the data..
printf("%s",apartments[i][j].family);
OR
puts(apartments[i][j].family);

consider creating structs holding the information you need to store/retrieve. the header struct could look something like
typedef struct
{
short floors;
short apartments;
} header;
you do more structs for the other parts of the file.
then when you read (frwrite to write) from the file you do something like
header h;
fread( &h, sizeof(h), 1, fp );
now using the information in the header you can calculate how to read/write the rest of the file. for the rest of the file you would have other structs but I leave that for you to solve.

Related

How to fix infinite loop with struct in C

I have a problem with the struct when storing data. I want to make a sentinel loop so please have a look and help me thank you.
#include<stdio.h>
#include<stdlib.h>
struct Vehichle
{
char vecType[100];
char plateNo[10];
float hours;
};
struct Parking
{
int parkNo ;
// 1 =true 0=false
int availability;
};
int main()
{
int c = 0;
int x;
struct Vehichle vehicle[c];
struct Parking park[50];
int counter = 1;
while(x!=-1)
{
printf("Enter -1 to end: \n");
scanf("%d", &x);
printf("Enter Vehicle Type etc: suv,mpv and more:");
scanf("%d",&vehicle[x].vecType);
printf("Please enter parking Number :");
scanf("%d",&park[x].parkNo);
park[x].availability = 1;
counter++;
}
}
I expect that after it is stored in the struct, the program will loop.
There are a number of problems in your code. Here is your code where I have added some comments:
int main()
{
int c = 0;
int x; // UPS: x is uninitialized
struct Vehichle vehicle[c]; // UPS: c is zero so you don't get an array
struct Parking park[50];
int counter = 1;
while(x!=-1) // UPS: Use of uninitialized x
{
printf("Enter -1 to end: \n");
scanf("%d", &x);
printf("Enter Vehicle Type etc: suv,mpv and more:");
scanf("%d",&vehicle[x].vecType); // UPS: vecType is char array so
// use %s instead of %d
// and don't use a &
printf("Please enter parking Number :");
scanf("%d",&park[x].parkNo);
park[x].availability = 1;
counter++;
}
}
Besides that you have a problem when the user input is -1. The current code just continues and adds an element at index -1. That's illegal.
To fix add an extra line after the scanf. Like:
scanf("%d", &x);
if (x == -1) break; // Stop the while loop
With that change you can do while(1) instead of while(x!=-1)
Some extra comments:
You should check that the user input (aka x) is within the valid range to be used as array index.
You should also check the return value of scanf. Like:
if (scanf("%d", &x) != 1)
{
// Invalid input"
... error handling ...
}
(1) Below is an updated code as your code had several problems.
I'm sure that looking at the below code, you would be able to understand the mistakes in your code.
Feel free to use this as the base for writing your own version.
(2) Please read the inline comments carefully. The comments elaborately
explain the intention of that section of code
(3) This is just a quick code. I've not compiled/run/tested this code.
My intention is just to give you an idea about it with one possible example.
/* A very basic parking manager module
When a vehicle comes in for parking
a)capture vehicle info & parking lot number where it is parking
b)mark that lot as unavailable
When the vehicle is leaving the parking,
capture parking lot number which is being emptied,
and mark that lot as available
And, have some fun on the way.
*/
#include<stdio.h>
#define YOU_ARE_TRAPPED_BY_THE_BIG_BAD_GREEN_SCARY_MONSTER ({printf("HA HA HA, You didn't read and follow the inline comments !!\nNow stand up, jump 3 times, then sit down, and read all the comments again and do the min code modif to make me go away, else i won't let you escape the parking lot ... hoo ha ha ha ha >-)\n"); updateVehicleParkingInfo=1;})
#include<stdlib.h>
struct Vehichle{
char vecType[100]; //type of vehicle eg suv,mpv and more...
char plateNo[10]; //number plate of the vehicle
float hours; //???
};
struct Parking{
int parkNo ; //parking lot num
bool availability; //Is tbis parking space available? Yes/No
};
struct VehicleParkingInfo{
struct Vehicle vehicle; //vehicle info
struct Parking parking; //corresponding parking info
};
//maximum number of parking lots that the parking space has
#define MAX_PARKING_LOTS 10
//parking lot avaialble flags
#define PARKING_LOT_AVAILABLE true
#define PARKING_LOT_UNAVAILABLE false
//flags for vehicle coming in or leaving
#define VEHICLE_ENTERING true
#define VEHICLE_LEAVING false
void main(){
int updateVehicleParkingInfo; //flag indicating that user wants to update parking info.
int vehicleDirection; //flag for indicating whether the vehicle is coming in or going out of the parking
int parkingIdx; //index of the parking lot to fetch values from.
//array for info about all the parking lots
struct VehicleParkingInfo vehicleParkingInfo[MAX_PARKING_LOTS];
//initialize the parking & vehicle info of all the parking lots to zeros
memset(vehicleParkingInfo,0,MAX_PARKING_LOTS*sizeof(VehicleParkingInfo));
//for each parking lot, mark it as available and assign parking lot numbers serially
for(parkingIdx = 0; parkingIdx < MAX_PARKING_LOTS; parkingIdx++){
vehicleParkingInfo[parkingIdx].parking.parkNo = parkingIdx;
vehicleParkingInfo[parkingIdx].parking.availability = PARKING_LOT_AVAILABLE;
}
//get user's input if parking info needs to be updated or it is time to close and go home
printf("Update parking info? Enter 0 to end");
scanf("%d",&updateVehicleParkingInfo);
/*
**** SENTINEL LOOP ****
Continue updating the parking info until the user wants to even for unlimited number of times.
Stop only when user enters a specific value i.e. 0.
*/
while(updateVehicleParkingInfo != 0){
printf("vehicle direction? 1 for entering, 0 for leaving:");
scanf("%d",&vehicleDirection);
if(vehicleDirection == VEHICLE_ENTERING){
do{
printf("Please enter parking Number:");
scanf("%d",&parkingIdx);
//*** CRASH ALERT!!! *** Following code can crash if parkingIdx is < 0, or >= MAX_PARKING_LOTS
//TODO: (1) Add sanity check for parkingIdx (2) Add corrective steps if sanity check fails
//if parking is not available, print an error message
if(vehicleParkingInfo[parkingIdx].parking.availability == PARKING_LOT_UNAVAILABLE){
//TODO: change the below messages to fine-tune fun, humor, teasing etc levels (remember humor setting of TARS from Interstellar?)
printf("There is some other vehicle parked in this parking lot, please enter another parking lot number\n");
printf("BTW, I know which lots are available, but I won't tell you ... hehehe >-) \n, keep trying ...hoo hoo hooo\n");
}
//check if the requested parking lot is available, if yes, then take further actions, else request a new parking lot number
}while(vehicleParkingInfo[parkingIdx].parking.availability == PARKING_LOT_UNAVAILABLE);
printf("Yipee, this parking lot is available\n");
//mark this parking lot number as being used so that another vehicle cannot come here.
vehicleParkingInfo[parkingIdx].parking.availability = PARKING_LOT_UNAVAILABLE;
//get vehicle type info and
// *** CRASH ALERT!!! *** The scanf below will crash if the user enters more 99+ characters (buffer overflow)
// Best is to use fgets or getline with the stdin as the stream.
// Ref https://stackoverflow.com/questions/4023895/how-do-i-read-a-string-entered-by-the-user-in-c
// TODO: Replace below scanf() with a better/safer implmentation
printf("Enter Vehicle Type etc: suv,mpv and more:");
scanf("%s",vehicleParkingInfo[parkingIdx].vehicle.vecType);
//TODO: other steps.
}
if(vehicleDirection == VEHICLE_LEAVING){
do{
printf("Please enter parking Number:");
scanf("%d",&parkingIdx);
//*** CRASH ALERT!!! *** Following code can crash if parkingIdx is < 0, or >= MAX_PARKING_LOTS
//TODO: (1) Add sanity check for parkingIdx (2) Add corrective steps if sanity check fails
//if parking is available, print an error message
if(vehicleParkingInfo[parkingIdx].parking.availability == PARKING_LOT_AVAILABLE){
printf("It appears that the parking lot number is incorrect, please enter correct parking lot number\n");
}
//check if the requested parking lot is available, if yes, then request a new parking lot number, else proceed further
}while(vehicleParkingInfo[parkingIdx].parking.availability == PARKING_LOT_AVAILABLE);
printf("Bye bye, drive safely\n");
//mark this parking lot number as available for other incoming vehicles.
vehicleParkingInfo[parkingIdx].parking.availability = PARKING_LOT_AVAILABLE;
}
//get user's input if parking info needs to be updated or it is time to close and go home
printf("Update parking info? Enter 0 to end");
scanf("%d",&updateVehicleParkingInfo);
//TODO: remove the following line of code before running the program
YOU_ARE_TRAPPED_BY_THE_BIG_BAD_GREEN_SCARY_MONSTER;
//go back to while loop,
//check if the vehicle parking info needs to be updated,
//break if the user has entered 0
}//end of the Sentinel loop
//the above loop will run indefinitely. The user has quite a lot of ways to come out of the loop
//(1) Enter the sentinel value '0', (easiest path)
//(2) Somehow stop the program e.g. by banging his/her head really hard on the computer such that computer breaks .. etc
}//end of main()

while loop for scanning user input table into array

I am a super unintuitive beginner programming student working on a homework assignment. The program is to take an input table of hockey teams and game stats, calculate "points", and then output the table organized in a different way, with additional columns for points and games played.
So far, I haven't made it past scanning the input. With my while loop, I'm trying to first determine if the string is a conference name or a team name and then scan and store the subsequent table values accordingly. I'm just trying to print the same table back out at this point, but when i copy/paste the input input table which was given, I get no output, and when I manually type it in, it comes out suuper weird.
The input table looks something like this:
Conference1_Name 3 (teams in conference)
Team_1_Name 31 15 2 2 (wins, losses, ot losses, shootout losses)
Team_2_Name 24 21 1 0
Team_3_Name 27 19 0 2
Conference2_Name 4
Team_4_Name 30 15 1 1
...
aaand this is my code so far...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
int main(void){
int n=0, N=25, nE=0, nW=0, i, w[n], l[n], otl[n], sol[n], gp[n], pts[n];
char input[30], team[n][30];
printf("Enter conference data\n");
setvbuf(stdout,NULL,_IONBF,0);
while(n<=N){
scanf("%s", input);
if (0==strcmp(input, "Eastern_Conference")) {
scanf("%d", &nE);
continue; //does not count eastern conference as a team, but stores number of teams, and does not increment n
}
if (0==strcmp(input, "Western_Conference")) {
scanf("%d", &nW);
continue; //does not count western conference as a team, but stores number of teams, and does not increment n
}
if (0==strcmp(input, "EOD")) break;
//originally i had a statement like: if (nE>0 && nW>0){N=nE+nW;) so that the loop condition n<N will break the loop on it's own but thought maybe EOD would simplify it and fix my problem//
strcpy(team[n], input);
scanf("%d%d%d%d", &w[n], &l[n], &otl[n], &sol[n]);
gp[n]=w[n]+l[n];
pts[n]=(2*w[n])+otl[n]+sol[n];
n++;
} //so we have input the data and calculated points
printf("\n%s\t%s\t%s\t%s\t%s\t%s\t%s\n", "WHL", "GP", "W", "L", "OTL", "SL", "PTS");
for(i=0; i<n; i++){
printf("%s\t%d\t%d\t%d\t%d\t%d\t%d\n", team[i], gp[i], w[i], l[i], otl[i], sol[i], pts[i]);
}
return EXIT_SUCCESS;
}

Trouble with populating student's marks

This is in response to a similar threat I posted the other day with reading a file into the requisite data structure with the file data like so, I can't remember who said it but yes there's four subjects. (I wanted to post an overall reply to all responses but could only comment on each post made):
131782 Mathematics 59
075160 Mathematics 92
580313 Physics 63
073241 Mathematics 32
487476 Mathematics 73
075160 Physics 98
472832 English 44
...
I'm using fscanf() now to parse the data and this is a much better approach. I made another thread yesterday about removing duplicate strings. I've scrapped that idea now and just used qsort on the student IDs and created a for loop that skips every four elements and rings the unique student IDs into the structure. I did a printf() command earlier and they're successfully stored. Now I've got the IDs stored I'm now ready to search for that ID and populate their marks and I "think" it's almost there except for a slight problem inside the update_student() function.
If you look at my code, or even compile it, it's not liking the line that's supposed to populate the mark for the student, student_data[idx].marks[buffer_subjects]=marks. But buffer_subjects is a string but if you look at my defines those strings are constants which is the whole idea when it gets to this stage.
How can I fix this?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STUDENTS 20
#define COMPUTING 0
#define ENGLISH 1
#define MATHEMATICS 2
#define PHYSICS 3
#define SUBJECTS 4
#define ROWS 80
#define SIZE 100
int string_compare(void const *x, void const *y)
{
return strcmp(*(char**)x, *(char**)y);
}
struct student
{
char student_ID[SIZE];
int marks[SUBJECTS];
};struct student student_data[STUDENTS];
int find_student(char buffer_IDs[])
{
int j;
for(j=0;j<STUDENTS;j++)
if(strcmp(student_data[j].student_ID,buffer_IDs)==0)
return j;
}
void update_student(char buffer_IDs[], char buffer_subjects[], int marks[])
{
int idx = find_student(buffer_IDs);
student_data[idx].marks[buffer_subjects] = marks;
}
int main(void)
{
FILE *input;
int i,j, data_items;
char buffer_IDs[ROWS][SIZE];
char buffer_subject[ROWS][SIZE];
int marks[ROWS][SIZE];
char *string_ptrs[ROWS];
if((input=fopen("C:\\marks\\marks.txt","r"))==NULL)
perror("File open failed!");
else
{
for(i=0;i<ROWS;i++)
{
while((data_items=fscanf(input, "%s %s %d", buffer_IDs[i], buffer_subject[i], marks[i])!=3));
printf("%s %s %d\n", buffer_IDs[i], buffer_subject[i], *marks[i]);
string_ptrs[i]=buffer_IDs[i];
}
putchar('\n');
qsort(string_ptrs, sizeof(string_ptrs)/sizeof(char*), sizeof(char*), string_compare);
for(i=0;i<ROWS;i=i+4)
{
j=0;
strcpy(student_data[j].student_ID,string_ptrs[i]);
printf("%s\n",student_data[j].student_ID);
j++;
}
for(i=0;i<ROWS;i++)
update_student(buffer_IDs[i], buffer_subject[i], marks[i]);
}
return 0;
}
> Blockquote
There are numerous failures in this block of code. I would seriously recommend building it up block by block, and using a debugger to confirm that the data in each stage is as expected, and not proceeding till each of the lower level blocks work (and do not produce compile errors).
Running it through GDB with some sample data suggests problems even at the point of reading in and parsing data from the file on disk.
We can assist with individual issues as they arise from this approach.

C: How to properly output struct from .txt file?

First time I have asked a question here. First here's the code:
void displayCompanyInfo(STAFF e[], int *s)
{
FILE *payRoll;
int i = 0;
int rosterNumber [100];
int count = 1;
if ((payRoll = fopen("payRoll.txt", "r")) == NULL)
{
perror ("error");
exit (0);
}
cls;
while (fgets(e[i].name, sizeof(e[i].name), payRoll) != NULL)
{
printf ("Record %i: ", count++);
printf("%s\n", e[i].name);
}
fclose(payRoll);
printf("\n\n");
pause;
cls;
} // end of display
Basically this code works. However when the text file displays it reads like this:
Record 1: Name: blah
Record 2: Age: 23
Record 3: Hourly Rate: 34
Instead I want it to read it as follows:
Record 1: Name: Blah
Age: 23
Hourly Rate: 34
Record 2: Name: Blah2
Age: 24
Hourly Rate: 35
And so on...
Any idea on how I can get this to work. I didn't post whole program because I didn't want to over do my thread. But if you need it let me know.
To this case you have to work with binary file handling.With text file it is not possible.
You have to read,write chunk of data in terms of bytes and handle it accordingly to retrieve you structure.
Say
struct e{
char name[20],
int age,
int hourly_rate
};
This structure will require
20(name) + 4(age) + 4(hourly_rate) bytes.Then you should write 28 bytes at a time in binary file and retrieve 28 bytes accordingly,which is not possible in case of text file.Because text file considers every thing as character,say age=23 it considers age field as 2 bytes and if age=3,it consider it as 1 byte.But binary file considers both thing as 4 bytes which is actual size of integer.
So the solution to your problem is binary file handling.
The problem is that the loop considers each line as a record. Instead, a record should be 3 lines. So read 3 things in the loop - add the 2 missing right before the printf.

C Primer 5th - Task 14-6

A text file holds information about a softball team. Each line has data arranged as follows:
4 Jessie Joybat 5 2 1 1
The first item is the player's number, conveniently in the range 0–18. The second item is the player's first name, and the third is the player's last name. Each name is a single word. The next item is the player's official times at bat, followed by the number of hits, walks, and runs batted in (RBIs). The file may contain data for more than one game, so the same player may have more than one line of data, and there may be data for other players between those lines. Write a program that stores the data into an array of structures. The structure should have members to represent the first and last names, the at bats, hits, walks, and RBIs (runs batted in), and the batting average (to be calculated later). You can use the player number as an array index. The program should read to end-of-file, and it should keep cumulative totals for each player.
The world of baseball statistics is an involved one. For example, a walk or reaching base on an error doesn't count as an at-bat but could possibly produce an RBI. But all this program has to do is read and process the data file, as described next, without worrying about how realistic the data is.
The simplest way for the program to proceed is to initialize the structure contents to zeros, read the file data into temporary variables, and then add them to the contents of the corresponding structure. After the program has finished reading the file, it should then calculate the batting average for each player and store it in the corresponding structure member. The batting average is calculated by dividing the cumulative number of hits for a player by the cumulative number of at-bats; it should be a floating-point calculation. The program should then display the cumulative data for each player along with a line showing the combined statistics for the entire team.
team.txt (text file I'm working with):
4 Jessie Joybat 5 2 1 1
4 Jessie Joybat 7 3 5 3
7 Jack Donner 6 3 1 2
11 Martin Garder 4 3 2 1
15 Jaime Curtis 7 4 1 2
2 Curtis Michel 3 2 2 3
9 Gillan Morthim 9 6 6 7
12 Brett Tyler 8 7 4 3
8 Hans Gunner 7 7 2 3
14 Jessie James 11 2 3 4
12 Brett Tyler 4 3 1 3
Since I'm a beginner in C, either I misinterpreted the task from what was asked originally or it's unfairly complex (I believe the former is the case). I'm so lost that I can't think of the way how could I fill in by the criteria of index (player number) every piece of data, keep track of whether he has more than one game, calculate and fetch bat average and then print.
What I have so far is:
#define LGT 30
struct profile {
int pl_num;
char name[LGT];
char lname[LGT];
int atbat[LGT/3];
int hits[LGT/3];
int walks[LGT/3];
int runs[LGT/3];
float batavg;
};
//It's wrong obviously but it's a starting point
int main(void)
{
FILE *flx;
int i,jc,flow=0;
struct profile stat[LGT]={{0}};
if((flx=fopen("team.txt","r"))==NULL) {
fprintf(stderr,"Can't read file team!\n");
exit(1);
}
for( jc = 0; jc < 11; jc++) {
fscanf(flx,"%d",&i);
stat[i].pl_num=i;
fscanf(flx,"%s",&stat[i].name);
fscanf(flx,"%s",&stat[i].lname);
fscanf(flx,"%d",&stat[i].atbat[flow]);
fscanf(flx,"%d",&stat[i].hits[flow]);
fscanf(flx,"%d",&stat[i].walks[flow]);
fscanf(flx,"%d",&stat[i].runs[flow]);
flow++;
}
}
Advice 1: don't declare arrays like atbat[LGT/3].
Advice 2: Instead of multiple fscanf you could read the whole line in a shot.
Advice 3: Since the number of players is limited and the player number has a good range (0-18), using that player number as an index into the struct array is a good idea.
Advice 4: Since you need cumulative data for each player (no need to store his history points), then you don't need arrays of integers, just an integer to represent the total.
So:
#include <stdio.h>
#define PLAYERS_NO 19
typedef struct
{
char name[20+1];
char lastName[25+1];
int atbat;
int hits;
int walks;
int runs;
float batavg;
} Profile;
int main(int argc, char** argv)
{
Profile stats[PLAYERS_NO];
int i;
FILE* dataFile;
int playerNo;
Profile tmpProfile;
int games = 0;
for(i=0; i<PLAYERS_NO; ++i)
{
stats[i].name[0] = '\0';
stats[i].lastName[0] = '\0';
stats[i].atbat = 0;
stats[i].hits = 0;
stats[i].walks = 0;
stats[i].runs = 0;
}
dataFile = fopen("team.txt", "r");
if ( dataFile == NULL )
{
fprintf(stderr, "Can't read file team!\n");
exit(1);
}
for(i=0; i<PLAYERS_NO && !feof(dataFile); ++i, ++games)
{
fscanf(dataFile, "%d", &playerNo);
if ( playerNo <0 || playerNo > PLAYERS_NO )
{
fprintf(stderr, "Player number out of range\n");
continue;
}
fscanf(dataFile, "%s %s %d %d %d %d",
&tmpProfile.name,
&tmpProfile.lastName,
&tmpProfile.atbat,
&tmpProfile.hits,
&tmpProfile.walks,
&tmpProfile.runs);
printf("READ: %d %s %s %d %d %d %d\n",
playerNo,
tmpProfile.name,
tmpProfile.lastName,
tmpProfile.atbat,
tmpProfile.hits,
tmpProfile.walks,
tmpProfile.runs);
strcpy(stats[playerNo].name, tmpProfile.name);
strcpy(stats[playerNo].lastName, tmpProfile.lastName);
stats[playerNo].atbat += tmpProfile.atbat;
stats[playerNo].hits += tmpProfile.hits;
stats[playerNo].walks += tmpProfile.walks;
stats[playerNo].runs += tmpProfile.runs;
}
/* exercise: compute the average */
fclose(dataFile);
for(i=0; i<PLAYERS_NO; ++i)
{
if ( stats[i].name[0] == '\0' )
continue;
printf("%d %s %s %d %d %d %d\n",
i,
stats[i].name,
stats[i].lastName,
stats[i].atbat,
stats[i].hits,
stats[i].walks,
stats[i].runs);
}
return 0;
}
The first rule of programming: Divide and conquer.
So you need to identify individual operations. One such operation is "load one row of input", another is "look up a player". If you have some of those operations (more will come up as you go), you can start building your program:
while( more_input ) {
row = load_one_row()
player = find_player( row.name )
if( !player ) {
player = create_player( row.name )
add_player( player )
}
... do something with row and player ...
}
when you have that, you can start to write all the functions.
An important point here is to write test cases. Start with a simple input and test the code to read a row. Do you get the correct results?
If so, test the code to find/create players.
The test cases make sure that you can forget about code that already works.
Use a framework like Check for this.
If I were doing this, I'd start with a structure that only held one "set" of data, then create an array of those structs:
struct profile {
char name[NAMELEN];
char lname[NAMELEN];
int atbat;
int hits;
int walks;
int runs;
float batavg;
};
Since you're using the player's number as the index into an array, you don't need to store it into the structure too.
I think that will simplify the problem a little bit. You don't need to store multiple data items for a single player -- when you get a duplicate, you just ignore some of the new data (like the names, which should be identical) and sum up the others (e.g., at-bats, hits).

Resources