为什么fscanf在没有明确告知的情况下更改结构的值?
我试图将一个文本文件读入c语言中的一个结构,但在我的为什么fscanf在没有明确告知的情况下更改结构的值?,c,file-io,data-structures,scanf,C,File Io,Data Structures,Scanf,我试图将一个文本文件读入c语言中的一个结构,但在我的fscanf()循环的最后一次迭代中,它改变了存储在结构的第一部分和第二部分中的数字和文本 调试表明,此行为是由whilefscanf()循环引起的。虽然更改输入字符串的大小会阻止更改数字,但第一行PMs.Party[0]上的字符串仍然从=Labour更改为r。这是我的密码: #include<stdio.h> #include<stdlib.h> #include<math.h> #include<s
fscanf()
循环的最后一次迭代中,它改变了存储在结构的第一部分和第二部分中的数字和文本
调试表明,此行为是由while
fscanf()
循环引起的。虽然更改输入字符串的大小会阻止更改数字,但第一行PMs.Party[0]
上的字符串仍然从=Labour更改为r。这是我的密码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
void PartyPwr( int Runs, int Time[12], char Prty[12][15]);
struct Data
{
char *Name[12][15];
int StrtMnth[12];
int StrtYr[12];
int EndMnth[12];
int EndYr[12];
char Party[12][15]; // if this is 13 20 it runs without numbers changing.
int TimePwr[12];
};
int main(void)
{
int Max=0;
int i=0;
FILE *PriMins;
struct Data PMs;
if ((PriMins=fopen("PM.txt", "r")) == NULL)
{
printf("Error: PM.txt cannot be read.");
system("pause");
return(1);
}
while(fscanf(PriMins, "%s %d %d %d %d %s", &PMs.Name[Max], &PMs.StrtMnth[Max], &PMs.StrtYr[Max], &PMs.EndMnth[Max], &PMs.EndYr[Max], &PMs.Party[Max]) > 0)
{
PMs.TimePwr[Max]=((PMs.EndMnth[Max] +(PMs.EndYr[Max]*12)) - (PMs.StrtMnth[Max] + (PMs.StrtYr[Max]*12)));
printf("%s %d Total term %d\n",PMs.Name[Max], PMs.EndMnth[Max],PMs.TimePwr[Max]);
printf("Max val, %d bug check %d, %d, Party %s\n",Max, PMs.TimePwr[0], PMs.TimePwr[1], PMs.Party[0]);
Max++;
}
//PartyPwr(Max, PMs.TimePwr, PMs.Party);
//printf("%d, %d", PMs.TimePwr[0], PMs.TimePwr[1]);
fclose(PriMins);
system("pause");
return(0);
}
void PartyPwr( int Runs , int Time[12], char Prty[12][15])
int i=0;
int LabPwr=0;
int ConPwr=0;
for (i=0;i<Runs;i++)
{
printf("%s\n", Prty[i]);
if (strcmp(Prty[i],"Labour")==0)
{
LabPwr=(LabPwr+Time[i]);
}
if (strcmp(Prty[i],"Conservative")==0)
{
ConPwr=(ConPwr+Time[i]);
}
if ((strcmp(Prty[i],"Conservative")!=0) && (strcmp(Prty[i],"Labour")!=0))
{
printf("An invalid party was present in the list.");
}
}
printf ("Total Labour time in power: %d\nTotal Conservative time in power: %d\n", LabPwr, ConPwr);
}
编辑:我刚刚发现,如果数据中每个变量的大小都增加一个,那么代码运行时不会出现任何问题。我想这是某种溢出
编辑2:特别是如果
EndYr
是[13]而不是[12]则问题消除。保守的一词是12个字符,但您必须考虑每个C字符串末尾的空字符'\0'
这就是为什么在Party字段中使用13个字符的数组时代码可以工作的原因
你应该做什么
在scanf格式说明符中指定参与方字段的最大长度。例如,如果为party字段保留12个字符的数组:
fscanf(PriMins, "%s %d %d %d %d %11s", &PMs.Name[Max], &PMs.StrtMnth[Max], &PMs.StrtYr[Max], &PMs.EndMnth[Max], &PMs.EndYr[Max], &PMs.Party[Max])
您正在从文件中读取13条记录,由于所有数据项的大小均为12,因此只有空间存储其中的12条记录。如果将大小增加1,则有足够的空间容纳所有13条记录
struct Data
{
char Name[13][15];
int StrtMnth[13];
int StrtYr[13];
int EndMnth[13];
int EndYr[13];
char Party[13][15];
int TimePwr[13];
};
你真的想要char*Name[12][15]代码>?或者应该是字符名[12][15]代码>好的一点实际上我认为这是动态分配长度时留下的。如果我将所有变量的大小增加1,代码运行良好。所以我在某种意义上修复了它,但不知道为什么。文本文件似乎有13行,但所有数组只有12个元素。这很像溢出。我认为你的edit2不应该工作。你应该增加它们
struct Data
{
char Name[13][15];
int StrtMnth[13];
int StrtYr[13];
int EndMnth[13];
int EndYr[13];
char Party[13][15];
int TimePwr[13];
};