我在阅读空间的阅读输入方面有问题

发布于 2025-02-09 14:19:25 字数 1260 浏览 1 评论 0原文

我制作了此功能以获取输入:

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);
 }
....

我的问题是团队名称有一些空间喜欢“圣保罗”。我尝试了一些表格来解决,但是没有人解决我的问题。

我尝试了:

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);

谢谢你们。

I made this function to get input:

void entrada_dados(Time* time, int i){
    scanf("%s %d %d", time[i].nome, &time[i].gols_marcados, &time[i].gols_sofridos);
};

The input is in this form:

2
Campinense 
23
12
ABC
30
13

The main is:

int main(void) {

  int n = 0;
  scanf("%d", &n);
  
  for(int i = 0; i < n; i++){
    entrada_dados(time, i);
 }
....

My problem is when the team name have some space like to "São Paulo". I have tried some forms to solve, but no one solved my problem.

I tried:

void entrada_dados(Time* time, int i){
    fscanf(stdin, "%[^\n] %d %d", time[i].nome, &time[i].gols_marcados, &time[i].gols_sofridos);
};

and:

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);
  }

but in the first case the output have nothing, and second case the output miss some cases. Someone can help me to understand this problem?

Edit 1:
The definition of .name is:

typedef struct Time{
  char nome[100];
  int gols_marcados;
  int gols_sofridos;
} Time;

Edit 2:

Solution:
One way to solve it:

Try two fscanfs fscanf(stdin, " %[^\n]", time[i].nome);
fscanf(stdin, "%d %d", &time[i].gols_marcados, &time[i].gols_sofridos);

Thank you guys.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笨死的猪 2025-02-16 14:19:25

因为您必须处理带有空格的字符串,所以最好将fgets为它们使用。

但是混合fgetsscanf效果不佳。我们可以用scanf fgets替换为sscanf

要解码号码,我们可以使用strtolsscanf

我们利用time> time出现在a 上的每个元素/成员的事实输入文件中的单独行,因此我们可以为每行进行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=%d\n",
                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

Because you have to handle strings with spaces, it's better to use fgets for those.

But mixing fgets and scanf doesn't work too well. We can replace scanf with fgets followed by sscanf.

To decode numbers, we can use strtol or sscanf

We take advantage of the fact that each element/member of Time appears on a separate line in the input file, so we can do fgets for every line. This simplifies the code and makes error checking easier.


Here is the refactored code. It is annotated.

I didn't do this, but, if these sequences are done a lot, we can combine some of these sequences in helper functions to reduce some code replication (e.g. a function that combines the fgets followed by the 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=%d\n",
                tim->nome,tim->gols_marcados,tim->gols_sofridos);
        }
    }

    return 0;
}

Here is the program input:

3
Campinense
23
12
ABC
30
13
São Paulo
17
82

Here is the program output:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文