Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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
C中的分段错误在main中起作用,但在my函数中不起作用_C - Fatal编程技术网

C中的分段错误在main中起作用,但在my函数中不起作用

C中的分段错误在main中起作用,但在my函数中不起作用,c,C,我正在尝试创建一个程序,该程序将检查用户输入到文件中的名称,并查看该文件中出现的名称。然而,在我的getrawdata函数中,我不断遇到分段错误 代码如下: struct NameRecord{ // Holds all the name information int year; char name [31]; int frequency; }; void allCaps(char s[]){ //Capitalizes all of the characters

我正在尝试创建一个程序,该程序将检查用户输入到文件中的名称,并查看该文件中出现的名称。然而,在我的getrawdata函数中,我不断遇到分段错误

代码如下:

struct NameRecord{ // Holds all the name information
    int year;
    char name [31];
    int frequency;
};


void allCaps(char s[]){ //Capitalizes all of the characters of s
    int i=0;
    while (s[i])
        {
            s[i] = toupper(s[i]);
            i++;
        }
    printf("The name entered is now in all caps! %s", s);
}

int getRawData1(FILE* male, struct NameRecord records[], int currSize){
    int readResult;
    printf("The current size is %d", currSize);
    readResult=fscanf(&*male, "%d", &records[currSize].year);
}
//Main
int main (){
    char name [31];
    FILE *male;
    FILE *female;
    int size = 0;
    //Opening files
    male = fopen("malebabynames.csv", "r"); //Dont leave in home directory 
    female = fopen("femalebabynames.csv", "r");
    struct NameRecord records[160000];

    if ( male==NULL){
        printf ("Error: the data file does not exist");
    }
    if ( female==NULL){
        printf ("Error: the data file does not exist");
    }

    size = getRawData1(male, records, size);
    //Output   
    printf("Please enter a name: ");
    scanf("%s", name);
    allCaps(name);
}
修改代码-仍然崩溃 原文载于;这个版本是d

#包括
结构名称记录
{
国际年;
字符名[31];
整数频率;
};
结构名称记录记录[160000];
void allCaps(字符s[])
{
int i=0;
而(s[i])
{
s[i]=toupper(s[i]);
i++;
}
printf(“输入的名称现在已全部大写!%s”,s);
}
int getRawData1(文件*male,结构名称记录[],int currSize)
{
int readResult;
printf(“当前大小为%d”,currSize);
readResult=fscanf(男性,“%d,%[^,],%d\n”,&记录[currSize]。年份,
记录[currSize]。名称,记录[currSize]。频率);
while(readResult==3)
{
currSize++;
readResult=fscanf(男性,“%d,%[^,],%d\n”,&记录[currSize]。年份,
记录[currSize]。名称,&记录[currSize]。频率);
}
printf(“数组的大小为%d”,currSize);
返回值大小;
}
int main()
{
字符名[31];
档案*男;
档案*女;
int size=0;
男性=fopen(“malebabynames.csv”,“r”);
女性=fopen(“femalebaynames.csv”,“r”);
int i=0;
int readResult;
if(男性==NULL)
{
printf(“错误:数据文件不存在”);
}
if(女性==NULL)
{
printf(“错误:数据文件不存在”);
}
getRawData1(男性、记录、大小);
printf(“欢迎使用人气检查器名称\n========================================================================\n”);
printf(“请输入名称:”);
scanf(“%s”,名称);
allCaps(名称);
}

这实际上在VS2012中对我来说在启动时崩溃,因为这行代码:

struct namecord记录[160000]

我认为您可能超出了可用的堆栈空间。至少对我来说是这样!这个数字需要这么高吗?您可以根据从文件中读取的内容动态分配吗

根据Barmar下面的建议,您可以这样做来修复它(如果您确实需要160k条记录的静态分配):

换句话说,将其设置为全局变量,而不是堆栈上的变量

更新:此外,根据Jonathan Leffler的建议,您可以确保正确打开文件。如果文件未正确打开,您当前正在打印一条消息,但如果是这种情况,则不应继续执行

if (male == NULL)
{
    printf("Error: the data file does not exist");
    return EXIT_FAILURE;
}
if (female == NULL)
{
    printf("Error: the data file does not exist");
    return EXIT_FAILURE;
}

请注意编译器警告。如果没有收到编译器警告,请打开它们;如果仍然没有收到编译器警告,请使用更好的编译器

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition x.c -o x
x.c: In function ‘getRawData1’:
x.c:30:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 5 has type ‘int’ [-Wformat=]
                         records[currSize].name, records[currSize].frequency);
                         ^
x.c:30:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 5 has type ‘int’ [-Wformat=]
$
您缺少一个
&

                         records[currSize].name, &records[currSize].frequency);
(我已经添加了
#include
并将
static
放在函数前面,以消除编译器发出的其他警告。)


您还应该重新设计
getRawData1()的接口。


如果文件中的记录超过160000条,这可以防止缓冲区溢出。

getRawData1
中没有
return
语句,请确保打开编译器警告并注意它们-
gcc-Wall…
或同等版本会为您省去很多麻烦。对此,我深表歉意。实际上有一本,但我没有错抄过来。不过,这仍然是一个分段错误。这看起来是错误的。
&*male
@user3075178只是为了检查一下,你能用100条姓名记录试试你的程序吗?我意识到文件中可能有更多内容,但只是想看看这是否是分段错误的原因。或者将其设置为静态变量,而不是局部变量。它实际上与文件的大小有关,或者将文件大小减少到160;大多数学校练习不会有160000个条目。如果你真的需要那么多,那么我会更新以反映Barmar的建议。也许可以使用指针,堆栈上的指针不会导致溢出(它们不是那么大)。我希望我有代表投票支持你!!!非常感谢你,乔纳森,这真的帮了我大忙。我的错误现在已经纠正了,我继续做作业:D。再次感谢。
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition x.c -o x
x.c: In function ‘getRawData1’:
x.c:30:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 5 has type ‘int’ [-Wformat=]
                         records[currSize].name, records[currSize].frequency);
                         ^
x.c:30:25: warning: format ‘%d’ expects argument of type ‘int *’, but argument 5 has type ‘int’ [-Wformat=]
$
                         records[currSize].name, &records[currSize].frequency);
int getRawData1(FILE *fp, struct NameRecord records[], int maxSize)
{
    int readResult;
    printf("The maximum size is %d", maxSize);
    int currSize = 0;

    while (currSize < maxSize &&
           (readResult = fscanf(fp, "%d,%[^,],%d\n", &records[currSize].year,
                                records[currSize].name, &records[currSize].frequency)) == 3)
        currSize++;

    printf("The amount of data in the array is %d", currSize);
    return currSize;
}
num_male_names = getRawData1(male, records, 160000);