我编写了这个函数来获取输入:
void entrada_dados(Time* time, int i){
scanf("%s %d %d", time[i].nome, &time[i].gols_marcados, &time[i].gols_sofridos);
};
输入格式为:
2
Campinense
23
12
ABC
30
13
主要是:
int main(void) {
int n = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++){
entrada_dados(time, i);
}
....
我的问题是,当球队的名字有一些空间,如" s0保罗"。我试了一些方法来解决,但是没有一个能解决我的问题。
我试着:
void entrada_dados(Time* time, int i){
fscanf(stdin, "%[^n] %d %d", time[i].nome, &time[i].gols_marcados, &time[i].gols_sofridos);
};
:
void entrada_dados(Time* time, int i){
fgets(time[i].nome, 100, stdin);
scanf("%d", &time[i].gols_marcados);
scanf("%d", &time[i].gols_sofridos);
}
,但在第一种情况下,输出什么都没有,第二种情况下,输出遗漏了一些情况。有人能帮我理解一下这个问题吗?
编辑1:.name的定义是:
typedef struct Time{
char nome[100];
int gols_marcados;
int gols_sofridos;
} Time;
编辑2:
解决方案:一种解决方法:
Try two fscanfs fscanf(stdin, " %[^n]", time[i].nome);
fscanf(stdin, "%d %d", &time[i].gols_marcados, &time[i].gols_sofridos);
谢谢大家。
因为必须处理带有空格的字符串,所以最好使用fgets
。
但混合fgets
和scanf
效果不太好。我们可以用fgets
和sscanf
来代替scanf
。
解码数字,我们可以使用strtol
或sscanf
Time
的每个元素/成员出现在输入文件中单独的行这一事实,因此我们可以对每行执行fgets
。这简化了代码,使错误检查更容易。
这是重构的代码。
我没有这样做,但是,如果这些序列做了很多,我们可以在辅助函数中组合一些这些序列来减少一些代码复制(例如,将fgets
与sscanf
组合在一起的函数)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Time {
char nome[100];
int gols_marcados;
int gols_sofridos;
} Time;
// RETURNS: 1=valid, 0=syntax error
int
entrada_dados(Time *timelist, int i)
{
char buf[100];
char *cp;
Time *tim = &timelist[i];
int valid = 0;
do {
// get name
if (fgets(tim->nome,sizeof(tim->nome),stdin) == NULL)
break;
// strip newline
tim->nome[strcspn(tim->nome,"n")] = 0;
// get number using strtol
if (fgets(buf,sizeof(buf),stdin) == NULL)
break;
tim->gols_marcados = strtol(buf,&cp,10);
if (*cp != 'n')
break;
// get number using sscanf
if (fgets(buf,sizeof(buf),stdin) == NULL)
break;
if (sscanf(buf,"%d",&tim->gols_sofridos) != 1)
break;
// all input is okay
valid = 1;
} while (0);
return valid;
};
int
main(void)
{
int n = 0;
#if 0
scanf("%d", &n);
#else
char buf[100];
if (fgets(buf,sizeof(buf),stdin) == NULL)
exit(1);
sscanf(buf,"%d",&n);
#endif
// allocate sufficient space
Time *timelist = malloc(sizeof(*timelist) * n);
// read in data
int valid = 0;
for (int i = 0; i < n; i++) {
valid = entrada_dados(timelist, i);
if (! valid)
break;
}
// show the data
if (valid) {
for (int i = 0; i < n; i++) {
Time *tim = &timelist[i];
printf("nome='%s' gols_marcados=%d gols_sofridos=%dn",
tim->nome,tim->gols_marcados,tim->gols_sofridos);
}
}
return 0;
}
程序输入:
3
Campinense
23
12
ABC
30
13
São Paulo
17
82
程序输出:
nome='Campinense' gols_marcados=23 gols_sofridos=12
nome='ABC' gols_marcados=30 gols_sofridos=13
nome='São Paulo' gols_marcados=17 gols_sofridos=82