I have this text file with various records, each record has 4 fields, 3 strings of words and one number, for example
field one; field two; field three; 1
field one; field two; field three; 2
I need to sort those records according to the last number through an insertion sort algorithm, so the second record should be the first one in the list, since 2>1. To do that, i first need to store each record before comparing them, i'm having some problems with that.
I got this until now:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 100
struct Element
{
char one[100];
char two[100];
char three[100];
int st;
};
int main() {
int i;
struct Element elements[MAXLEN];
FILE * fpointer = fopen("clients.txt", "r");
for (i = 0; i < MAXLEN; i++) {
struct Element *e = elements+i; // pointer on ith element
fscanf(fpointer, "%99s%99s%99s%d", e->one, e->two, e->three, &e->st);
}
printf("%s%s%s%d", elements->one, elements->two, elements->three, elements->&st);
fclose(fpointer);
return 0;
}
My current problems:
1) this current program is not good for saving string of words. It's good when the record is like: string; string; string; 1 but it won't work with phrases (like in the first example).
2) I don't really understand the structure of this: i know that i'm saving each record in my array of data structures but i'm having some problems printing each record. Let's say i want to print the second record, how can i do that? In my current work i printed one, two, three and st but this way, it will only print the first record.
Using %s when calling any of the scanf functions just reads in text up to the next bit of whitespace, so will work fine if you have single words in your fields, but as you've discovered falls over if there phrases. It also will read in the delimiters into your strings too, which I doubt you want.
Instead, a better solution would be to read in the entire line into a string and parse your way through it. The following bit of code reads in a line of text with fgets and then uses strtok to split it up into chunks separated by semicolons. It keeps track of how which field it is populating using field_number so if you add more fields, it's easy to expand. And if there are less fields than expected it will stop and move onto the next line.
char buffer[1024]; // Define a really big string to hold the line of text in
char *field;
int field_number;
while(fgets(buffer,1024,fpointer))
{
field_number=0;
field=strtok(buffer,";");
while(field)
{
switch(field_number)
{
case 0:
strcpy(elements[i].one,field);
break;
case 1:
strcpy(elements[i].two,field);
break;
case 2:
strcpy(elements[i].three,field);
break;
case 3:
elements[i].st=atoi(field);
break;
}
field=strtok(NULL,";"); // Get next field
field_number++;
}
i++; // Move the index for elements to the next one
}
In answer to your second question, elements is an array. If you do elements->one that is the same as doing elements[0].one. If you want to access the second element in your array, you'd do elements[1].one or (elements+1)->one which is what you're doing with this odd line in your original code:
struct Element *e = elements+i; // pointer on ith element
when really you should have been using elements[i] as that is a lot easier to read.
You can use %[^;] in fscanf. fscanf will read the string until reaches ;.
And use ; as delimiter for fscanf.
Your code will look like below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 3
struct Element
{
char one[100];
char two[100];
char three[100];
int st;
};
int main() {
int i;
struct Element elements[MAXLEN];
FILE * fpointer = fopen("clients.txt", "r");
for (i = 0; i < MAXLEN; i++) {
struct Element *e = elements+i; // pointer on ith element
if (fscanf(fpointer, "%[^;];%[^;];%[^;];%d", e->one, e->two, e->three, &e->st) !=3)
break;
}
for (i = 0; i < MAXLEN; i++) {
struct Element *e = elements+i; // pointer on ith element
printf("%s%s%s%d\n", elements->one, elements->two, elements->three, elements->st);
}
fclose(fpointer);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With