问题
I have an archive results.csv
and I need to read the first two lines of this archive, split the second one and print them out on output.txt
. Somehow it's not printing anything, yet I don't know the reason.
I didn't add the functions that I'm sure are fine.
Command: a.c results.csv
First line:
date,home_team,away_team,home_score,away_score,tournament,city,country,neutral
Second line:
18721130,Scotland,England,0,0,Friendly,Glasgow,Scotland,FALSE
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct
{
char *line1;
long int date;
char *h_team;
char *a_team;
int gols_h_team;
int gols_a_team;
char *reason;
char *city;
char *country;
char *neutral_field;
}Data;
void alloc_Data(Data *d, int size)
{
d->line1 = (char*)malloc(50*sizeof(char));
d->h_team = (char*)malloc(30*sizeof(char));
d->a_team = (char*)malloc(30*sizeof(char));
d->reason = (char*)malloc(30*sizeof(char));
d->city = (char*)malloc(30*sizeof(char));
d->country = (char*)malloc(30*sizeof(char));
d->neutral_field = (char*)malloc(9*sizeof(char));
}
void store(Data *d, FILE *input, FILE *output, int size)
{
fscanf(input, "%s", d[0].line1);
fprintf(output, "%s\n", d[0].line1);
for(int i = 1; i < size; i++)
{
fscanf(input, "%li,%[^,]s%[^,]s%d,%d,%[^,]s%[^,]s%[^,]s%[^,]s", &d[i].date, d[i].h_team, d[i].a_team, &d[i].gols_h_team, &d[i].gols_a_team, d[i].reason, d[i].city, d[i].country, d[i].neutral_field );
fprintf(output, "%li,%s,%s,%d,%d,%s,%s,%s,%s\n", d[i].date, d[i].h_team, d[i].a_team, d[i].gols_h_team, d[i].gols_a_team, d[i].reason, d[i].city, d[i].country, d[i].neutral_field );
}
}
int main(int argc, char *argv[])
{
FILE *input;
FILE *output;
char *string = "output.txt";
int size = 2;
open_input(argv, &input);
open_output(string, &output);
Data *d;
d = (Data*)malloc(size*sizeof(Data));
alloc_Data(d, size);
store(d, input, output, size);
free(d);
return 0;
}
回答1:
OP's fscanf()
format is messed up with an s
after %[^,]
and missing ,
. @Gem Taylor
A better alternative is to read all lines using fgets()
. (including the first)
// fscanf(input, "%li,%[^,]s%[^,]s%d,%d,%[^,]s%[^,]s%[^,]s%[^,]s",...d[i].neutral_field );
#define EXPECTED_MAX_BUFFER_SIZE 150
char buffer[EXPECTED_MAX_BUFFER_SIZE * 2]; // suggest using 2x expected max size
if (fgets(buffer, sizeof buffer, input)) {
Then parse the team results with sscanf()
. Using a " %n"
at the end is an easy way to test if the entire sscanf()
succeeded with no extra junk. sscanf()
deserve width limits and complex scans benefit with some defines to manage the specifiers. Notice no s
after "%29[^,]"
int n = 0;
#define FDat "%li ,"
#define FScr "%d ,"
#define Ftxt " %29[^,],"
#define Fneu " %8[^,]"
sscanf(buffer, FDat Ftxt Ftxt FScr FScr Ftxt Ftxt Ftxt Fneu " %n",
&d[i].date, d[i].h_team, d[i].a_team,
&d[i].gols_h_team, &d[i].gols_a_team,
d[i].reason, d[i].city, d[i].country, d[i].neutral_field, &n);
if (n > 0 && buffer[n] == '\0') {
// success
fprintf(output, ...
} else {
// bad input
}
来源:https://stackoverflow.com/questions/50745686/splitting-a-long-string