我正在尝试创建一个程序,该程序将检查用户输入文件的名称,并查看文件中有多少次出现。但是在我的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);
}
#include <stdio.h>
struct NameRecord
{
int year;
char name[31];
int frequency;
};
struct NameRecord records[160000];
void allCaps(char 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,%[^,],%d\n", &records[currSize].year,
records[currSize].name, records[currSize].frequency);
while (readResult == 3)
{
currSize++;
readResult = fscanf(male, "%d,%[^,],%d\n", &records[currSize].year,
records[currSize].name, &records[currSize].frequency);
}
printf("The size of the array is %d", currSize);
return currSize;
}
int main()
{
char name[31];
FILE *male;
FILE *female;
int size = 0;
male = fopen("malebabynames.csv", "r");
female = fopen("femalebabynames.csv", "r");
int i = 0;
int readResult;
if (male == NULL)
{
printf("Error: the data file does not exist");
}
if (female == NULL)
{
printf("Error: the data file does not exist");
}
getRawData1(male, records, size);
printf("Welcome to the Name Popularity Checker \n====================================== \n");
printf("Please enter a name: ");
scanf("%s", name);
allCaps(name);
}
答案 0 :(得分:1)
由于这条线路,我在启动时实际上在VS2012中崩溃了:
struct NameRecord records[160000];
我认为您可能超出了可用的堆栈空间。至少这对我来说!这个数字需要这么高吗?你可以根据你从文件中读到的内容动态分配吗?
根据Barmar的建议,你可以这样做来解决它(如果你真的需要160k记录的静态分配):
struct NameRecord{ // Holds all the name information
int year;
char name [31];
int frequency;
};
NameRecord records[160000];
换句话说,将它设为全局变量而不是堆栈上的变量。
更新:此外,使用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;
}
答案 1 :(得分:1)
注意编译器警告。如果您没有收到编译器警告,请将它们打开;如果你仍然没有得到编译器警告,那就得到一个更好的编译器。
$ 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 <ctype.h>
并将static
放在函数前面以平息编译器发出的其他警告。)
您还应该重新设计getRawData1()
:
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);
如果文件中有超过160,000条记录,这可以防止缓冲区溢出。