我真的希望有人能帮助我,或者为我提供可以帮助的资源,因为我已经为此挣扎了好几个小时了。
我还没有太多的C语言或编码经验,我有一项任务,我需要将一个包含足球/足球比赛结果的txt文件读取到一个数组中,但我无法获得";fscanf";部分工作。
我已经创建了一个结构,其中包含了我需要保存和稍后处理的详细信息。(现在日期只是保存为字符串,或者我可以将该信息保存为2个整数DD-MM(。
我打电话给我的";file_ read";从main(int函数,因为我需要知道以后为qsort读取了多少行(,并传递我的";结构类型";数组和.txt文件作为该函数的参数。
在";file_ read";函数I有一个int变量用于计数,并打开main中指定的文件,检查NULL,然后"达到它";通过调用函数";read_ match";并将我的文件指针作为参数传递。
这就是我遇到麻烦的地方(根据更懂代码的人的说法,可能更早(!
我不知道如何使用%s和whatnot来区分文本文件的各个段(?(,以便能够将其正确地保存在各种结构类型中。
txt文件中的数据如下所示:
(day) (date)(time) (teamA)(teamB) (goalsA)(goalsB) (spectators)
Son 28/07 18.00 BIF - OB 3 - 2 13689
Man 29/07 19.00 AaB - SIF 3 - 1 5885
Fre 02/08 19.00 SIF - HOB 2 - 3 3468
(在上面的数据中添加了结构名称(
到目前为止,我的整个代码看起来是这样的:(滚动到底(
(我尝试了各种方法,如%[abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]%[0123456789]和下面的内容,但在txt文件中的第一个"-"之后似乎总是会出错。添加了一个打印功能用于故障排除(
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_SHORT 10
#define STR_LONG 70
#define MATCHES 300
typedef struct {
char day[STR_SHORT];
char date[STR_SHORT];
char time[STR_SHORT];
char team_A[STR_SHORT];
char team_B[STR_SHORT];
int goals_A;
int goals_B;
int spectators;
} Match;
int file_read(char *file_input, Match arr_matches[]);
Match read_match(FILE *file_ptr);
/*MAIN*/
int main(void) {
Match arr_matches[MATCHES];
int n;
n = file_read("data.txt", arr_matches);
printf(" %d", n);
return 0;
}
/*FUNCTIONS*/
int file_read(char *file_input, Match arr_matches[]) {
int r = 0;
FILE *file_ptr = fopen(file_input, "r");
if (file_ptr == NULL) {
printf("Error! Can't open file!");
return 1;
}
while(!(feof(file_ptr))){
arr_matches[r] = read_match(file_ptr);
++r;
}
fclose(file_ptr);
return r;
}
Match read_match(FILE *file_ptr) {
Match input;
fscanf(file_ptr, " %s %s %s"
" %s %7s"
" %2d %*[-] %2d"
" %d",
input.day, input.date, input.time,
input.team_A, input.team_B,
&input.goals_A, &input.goals_B,
&input.spectators);
printf("(day) %s (date) %s (time) %s (teamA) %s (teamB) %s (scoreA) %d (scoreB) %d (spect) %dn",
input.day, input.date, input.time, input.team_A, input.team_B, input.goals_A, input.goals_B, input.spectators);
return input;
}
非常感谢可用的反馈,如果需要详细说明,请告诉我。
谢谢!
编辑:我一直在尝试STRTOK,也许可以以某种方式将其结合起来。。。
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "Fre 12/07 19.00 FCM - EFB 1 - 0 7310 ";
const char s[] = "-' '";
char *token;
/* get the first token */
token = strtok(str, s);
/* walk through other tokens */
while( token != NULL ) {
printf( " %sn", token );
token = strtok(NULL, s);
}
return(0);
}
如何在txt文件的字符串上正确限制
fscanf
?(需要读取用空格and"-"分隔的字符串和整数(?
OP格式中缺少的关键部分是第一个'-'
和未能测试返回值。
// Son 28/07 18.00 BIF - OB 3 - 2 13689
// fscanf(file_ptr, " %s %s %s" " %s %7s" " %2d %*[-] %2d" " %d", ...
int cnt = fscanf(file_ptr, "%s%s%s" "%s -%7s" "%2d -%2d" "%d",
// ^
if (cnt == 8) Success();
同时回顾为什么"while(!feof(file(("总是错误的?
提示:与其使用fscanf()
读取数据的行,不如使用fgets()
。
char buf[100];
if fgets(buf, sizeof buf, file_ptr) == NULL) {
然后用sscanf()
、strtol()
等解析输入的行。
最好使用"%s"
的宽度限制
int cnt = fscanf(file_ptr, "%9s%9s%9s" "%9s -%9s" "%2d -%2d" "%d",
决定如何1(不再处理输入,2(错误输入。
一些未经测试的代码将这些想法结合在一起:
它还使用" %n"
来检测输入行的好部分之后的垃圾。
Match* read_match(FILE *file_ptr, Match *input) {
char buf[100];
if (fgets(buf, sizeof buf, file_ptr) == NULL) {
return NULL;
}
int n = 0;
if (sscanf(buf,
"%9s%9s%9s" "%9s -%9s" "%2d -%2d" "%d" " %n", //
input->day, input->date, input->time, //
input->team_A, input->team_B, //
&input->goals_A, &input->goals_B, //
&input->spectators, //
&n) != 8 || buf[n]) {
fprintf(stderr, "Invalid input "%s"n", buf);
return NULL;
}
return input;
}
int file_read(char *file_input, int n, Match *arr_matches) {
int r = 0;
FILE *file_ptr = fopen(file_input, "r");
if (file_ptr == NULL) {
printf("Error! Can't open file!");
return -1;
}
int i;
for (i = 0; i < n; i++) {
if (read_match(file_ptr, &arr_matches[i]) == NULL) {
break;
}
}
fclose(file_ptr);
return i;
}