Reputation: 19
How would I save different lines from a text File to different variables of different datatypes; all of these variables make up a struct (in my example a flight struct with the following).
struct Flight
{
int flightNum;
char desination[30];
char departDay[15];
};
An Example of the information that I would like to add via text file would be.
111
NYC
Monday
I obviously want to save the words NYC and Monday to a char array, but I want to save 111 to an integer variable
So far I have
while (fscanf(flightInfo, "%s", tempName) != EOF)
{
fscanf(flightInfo, "%d\n", &tempNum);
flight.flightNumber = tempNum;
fscanf(flightInfo, "%s\n", tempName);
strcpy(flight.desination, tempName);
fscanf(flightInfo, "%s\n", tempName)
strcpy(flight.departDay, tempName);
}
Assume that flightInfo is a pointer to a filename, tempNum is an integer, and tempName is a char array
Upvotes: 1
Views: 88
Reputation: 121649
It sounds like you're on the right track.
What about something like this:
#define MAX_FLIGHTS 100
...
struct Flight flights[MAX_FLIGHTS ];
int n_flights = 0;
...
while (!feof(fp) && (n_flights < MAX_FLIGHTS-1))
{
if (fscanf(fp, "%d\n", &flights[n_flights].flightNum) != 1)
error_handler();
if (fscanf(fp, "%29s\n", flights[n_flights].destination) != 1)
error_handler();
if (fscanf(fp, "%14s\n", flights[n_flights].departDay) != 1)
error_handler();
++n_flights;
}
...
ADDENDUM: Per Chux's suggestion, I've modified the code to mitigate against potential buffer overruns, by setting scanf max string length to 29 (1 less than char[30] buffer size).
Here is a more detailed explanation:
Upvotes: 1
Reputation: 785
The first question you have to answer is this: how important is it for the file to be readable by people, or on other platforms?
If it isn't that important, then I recommend serializing with fwrite()
and fread()
. That is easier to code for each record, and - as long as your structs are all the same size - allows O(1) access to any record in the file.
If you do want to store these as individual lines, the best way to read a line in from a file is with fgets()
Pseudocode follows:
typedef struct flight {
int flightNum;
char desination[30];
char departDay[15];
} flight;
typedef struct flightSet {
flight *flights;
size_t n; /* number of flights */
size_t nAlloc; /* number of flights you have space for */
} flightSet;
#define FLIGHTSET_INIT_SIZE 16
#define MAX_LINE_LENGTH 128
#define FILENAME "file.txt"
// Create a new flightSet, calling it F
// Allocate FLIGHTSET_INIT_ALLOC number of flight structures for F->flights
// Set F->n to 0
// Set F->nAlloc to FLIGHTSET_INIT_ALLOC
/* Set up other variables */
size_t i = 0; // iterator */
char buffer[MAX_LINE_LENGTH]; // for reading with fgets() */
flights *temp; // for realloc()ing when we have more flights to read
// after reaching nAlloc flights
char *endptr; // for using strtol() to get a number from buffer
FILE *fp; // for reading from the file
// Open FILENAME with fp for reading
//MAIN LOOP
// If i == F->nAlloc, use realloc() to double the allocation of F->flights
// If successful, double F->nAlloc
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file
// Use break to get out of the main loop
}
F->flights[i]->flightNum = (int)strtol(buffer, &endptr, 10);
if (endptr == buffer) {
// The first invalid character that can't be converted to a number is at the very beginning
// of the buffer, so this is not a valid numerical character and your data file is corrupt
// Print out an error message
break;
}
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file when expecting new line; file format error
// Use break to get out of the main loop
} else {
F->flights[i]->destination = strdup(buffer); // If your system has strdup()
// Check for memory allocation
}
if (fgets(buffer, MAX_LINE_LENGTH, fp) == NULL) {
// End of file when expecting new line; file format error
// Use break to get out of the main loop
} else {
F->flights[i]->departDay = strdup(buffer); // If your system has strdup()
// Check for memory allocation
}
// If you've gotten here so far without errors, great!
// Increment F->n to reflect the number of successful records we have in F.
// Increment i, the loop iterator
//Final cleanup. Should include closing the file, and freeing any allocated
//memory that didn't end up in a valid record.
Upvotes: 0