[英]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.