c语言 - 如何正确限制 txt 文件中的字符串上的 fscanf?(需要读取用空格和"-"分隔的字符串和整数)



我真的希望有人能帮助我,或者为我提供可以帮助的资源,因为我已经为此挣扎了好几个小时了。

我还没有太多的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;
}

最新更新