Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么fscanf在没有明确告知的情况下更改结构的值?_C_File Io_Data Structures_Scanf - Fatal编程技术网

为什么fscanf在没有明确告知的情况下更改结构的值?

为什么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

我试图将一个文本文件读入c语言中的一个结构,但在我的
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];
};