So I have a .txt file which is as following:
** Paris ** Flight,5 days,visiting various monuments. | 2999.99 |
** Amsterdam ** By bus,7 days, local art gallery. | 999.99 |
** London ** Flight,3 days,lots of free time. | 1499.99 |
I want to get the information stored into 3 variables, city, description and price, but I can't get it to save the lines at all.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char city[256],desciption[256];
float temp;
if(fp=fopen("Ponuda.txt","rt")==NULL){
printf("ERROR\n");
exit(1);
}
while(fscanf(fp,"** %s ** %s | %f |",city,description,&temp)==3){
printf("** %s ** %s |%f|\n",city,description,temp);
}
return 0;
IMO it is much easier to read each file line with fgets
, and then use strtok
to split each line with the delimiter string "*|"
.
Then I use strdup
to duplicate the text strings into the struct, and sscanf
to extract the fare from the third token. I should have tested the return value from strdup
, as it calls malloc
internally.
I also use double
instead of float
(which I will only use if there are constraints).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10
typedef struct {
char *city;
char *descrip;
double fare;
} flight_t;
int main()
{
FILE *fp;
flight_t visit[MAX] = {0};
char buffer [1024];
char *tok;
int records = 0, i;
if((fp = fopen("Ponuda.txt", "rt")) == NULL) {
printf("Error opening file\n");
exit(1);
}
while(fgets(buffer, sizeof buffer, fp) != NULL) {
if((tok = strtok(buffer, "|*")) == NULL) {
break;
}
if(records >= MAX) {
printf("Too many records\n");
exit(1);
}
visit[records].city = strdup(tok); // add NULL error checking
if((tok = strtok(NULL, "|*")) == NULL) { // pass NULL this time
break;
}
visit[records].descrip = strdup(tok); // add NULL error checking
if((tok = strtok(NULL, "|*")) == NULL) { // pass NULL this time
break;
}
if(sscanf(tok, "%lf", &visit[records].fare) != 1) { // read a double
break;
}
records++;
}
fclose(fp);
// print the records
for(i = 0; i < records; i++) {
printf("** %s ** %s |%.2f|\n", visit[i].city, visit[i].descrip, visit[i].fare);
}
// free the memory given by strdup
for(i = 0; i < records; i++) {
free(visit[i].city);
free(visit[i].descrip);
}
return 0;
}
Program output:
** Paris ** Flight,5 days,visiting various monuments. |2999.990000|
** Amsterdam ** By bus,7 days, local art gallery. |999.990000|
** London ** Flight,3 days,lots of free time. |1499.990000|
This is very difficult to do with a single fscanf statement, since, as @Barmar pointed out, the city name may be more than one word. It is much easier to read the entire line (using fgets) and then parsing the line yourself. To parse it:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.