简体   繁体   English

使用sscanf从文件中读取时,变量将覆盖其他变量

[英]variable is overwriting other variable when reading from a file using sscanf

#include <stdio.h>
#include <stdlib.h>

#define MAX 21
#define MAX_ELEM 8
#define SCORE 12
#define NUM_SKATER 4
#define BASE 3.1

typedef struct{
                char  name[MAX];
                int   elements;
                float baseval[MAX_ELEM];
                int score[MAX_ELEM][SCORE];
                float total_base;
                float tech_score;
                float total_score;
              }SKATER;

int  getData(SKATER skater[NUM_SKATER]);



int main (void)
{
    // Global Declarations
    SKATER skater[NUM_SKATER];

    // Function calls
    getData(skater);
    return 0;
}

/********************************* getData ************************************
Pre:
Post:
*/
int getData(SKATER skater[NUM_SKATER])
{
    // LOcal Declarations
    FILE* fpIn;
    int   i = 0;
    int   k;
    int   j;
    char  buffer[256];

    // Statements
    if((fpIn = fopen("lab6data.txt","r"))==NULL)
    {
        printf("File opening error");
        system("PAUSE");
        exit(100);
    }

    while(i < NUM_SKATER && fgets(buffer, sizeof(buffer) - 1, fpIn))
    {
        sscanf(buffer,"%19[^0123456789]", &skater[i].name);
        for(k = 0; k < MAX_ELEM; k++)
        {puts(buffer);
            if(fgets(buffer, sizeof(buffer)-1, fpIn) != NULL)
            {
                sscanf(buffer,"%d %f", &skater[i].elements, &skater[i].baseval[k]);
                for(j = 0; j < SCORE; j++)
                {
                    sscanf(buffer,"%d", &skater[i].score[k][j]);

                }
            }

       }

        i++;
    }

    system("PAUSE");
    fclose(fpIn);

    return i;
}

I am having some trouble with reading the data from the file, so when I add a printf to the sscanf of the score and found out that it was actually print out the element numbers but not the score. 我从文件中读取数据时遇到了一些麻烦,因此当我在分数的sscanf中添加一个printf时,发现它实际上是打印出元素编号而不是分数。 I am confused about how this happen. 我对这种情况如何感到困惑。

Can anyone suggest away to fix this or explain to me what happen to the score? 谁能建议解决这个问题或向我解释分数发生了什么?

lets say that the sample data was 1 13.0 1 2 3 0 0 0 2 1 0 3 假设样本数据为1 13.0 1 2 3 0 0 0 2 1 0 3

with the first number being the elements number, the second number is the base number and the rest is scores now that i wanted to print out score it would print out 1 1 1 1 1 1 1 1 1 1 第一个数字是元素编号,第二个数字是基数,其余的是分数,现在我想打印分数,它将打印出来1 1 1 1 1 1 1 1 1 1 1
instead of 1 2 3 0 0 0 2 1 0 3 而不是1 2 3 0 0 0 2 1 0 3

The problem you have is that you are assuming that sscanf does some magic, namely that it remembers where it was in buffer after the last time it was called. 您遇到的问题是,您假设sscanf做了一些魔术,也就是说,它记住了上次调用后它在buffer的位置。

sscanf does no such magic, it will being processing at the start of the string you give it, no matter how many times you've called it before with that same string. sscanf没有这种魔力,它将在您给它的字符串开头处进行处理,无论您之前使用相同的字符串调用过多少次。

So the nested 所以嵌套

sscanf(buffer,"%d", &skater[i].score[k][j]);

is always reading the very first int in buffer , ie 1 in your sample. 总是读取buffer第一个int ,即样本中的1 There is no "overwriting" going on, you're just reading the same thing over and over again. 没有“覆盖”的情况发生,您只是一遍又一遍地阅读同一件事。

To make this work, you'll need to keep track of where you should restart parsing yourself. 要使此工作正常进行,您需要跟踪应该在哪里重新解析自己的位置。 This can be done by using the %n format specifier, and a "cursor" char * into your buffer for example. 例如,可以使用%n格式说明符,并在缓冲区中使用“游标” char *来完成此操作。

Here's a sample of how you use that: 以下是使用方式的示例:

#include<stdio.h>
#include<stdlib.h>

int main(int argc, char **argv)
{
    int val;
    int pos;
    char *cur = argv[1];
    printf("Input: [%s]\n", cur);
    while (sscanf(cur, "%d%n", &val, &pos)==1) {
        printf("Read %d, rest is [%s]\n", val, cur+pos);
        cur += pos;
    }
    return 0;
}

Try running this code with different parameters: 尝试使用不同的参数运行此代码:

$ gcc -Wall t.c
$ ./a.out "1"
Input: [1]
Read 1, rest is []
$ ./a.out "1 2"
Input: [1 2]
Read 1, rest is [ 2]
Read 2, rest is []
$ ./a.out "1 a 2"
Input: [1 a 2]
Read 1, rest is [ a 2]
$ ./a.out "1 2 3 54"
Input: [1 2 3 54]
Read 1, rest is [ 2 3 54]
Read 2, rest is [ 3 54]
Read 3, rest is [ 54]
Read 54, rest is []
$ ./a.out "1.0 2 3 54"
Input: [1.0 2 3 54]
Read 1, rest is [.0 2 3 54]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM