我正在编写一个应该查看文件的程序加载它,你应该在编译后使用命令./main(searchingname)在列表中搜索一个名字。编译时我没有错误。但是当我尝试搜索名称时,我立即得到一个段错误,程序终止。这是我的代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _data {
char *name;
long number;
};
int SCAN(FILE *(*stream)) {
int lines = 0;
*stream = fopen("hw5.data", "r");
char c_temp[100];
long l_temp;
while(!feof(*stream)) {
fscanf(*stream, "%s %ld", c_temp, &l_temp);
lines++;
}
return lines;
}
struct _data *LOAD(FILE *stream, int size) {
struct _data *temp;
stream = fopen("hw5.data", "r");
char c_temp[100];
long l_temp;
int i;
rewind(stream);
for(i = 0; i < size; i++) {
fscanf(stream, "%s %ld", c_temp, &l_temp);
temp[i].name = calloc(strlen(c_temp), sizeof(char));
strcpy(temp[i].name, c_temp);
}
return temp;
}
void SEARCH(struct _data *Blackbox, char *name, int size) {
int found = 0, i, entry;
for(i = 0; i < size; i++) {
if((strcmp(Blackbox[i].name, name)) == 0) {
found = 1;
entry = i;
}
}
if(found == 1) {
printf("The name you are looking for has been found at entry: %d\n", entry);
} else {
printf("Entry not found.\n");
}
}
void FREE(struct _data *Blackbox, int size) {
int i;
for(i = 0; i < size; i++) {
free(Blackbox[i].name);
}
}
int main(int argv, char **argc) {
struct _data *Blackbox;
if(argv == 1) {
printf("*******************************************\n");
printf("*You must include a name to search for. *\n");
printf("*******************************************\n");
} else {
FILE *(*data);
int lines = SCAN(data);
printf("%d", lines);
Blackbox = LOAD(*data, lines);
SEARCH(Blackbox, argc, lines);
}
}
该文件看起来像这样
foo 7894898,
bar 7895497
.
.
.
答案 0 :(得分:1)
原因是你没有为阵列分配空间,但是你还有很多其他小问题会让你的程序产生奇怪的行为。
在每次调用fopen()
后,您都不会检查文件是否已打开,您需要确保返回的值不是NULL
。
FILE *stream = fopen(filename, "r");
if (stream == NULL)
/* do not try to read from stream */
while(!feof(file))
总是错误的,无论如何都要将错误的值传递给feof()
,以计算文件中有效行的数量,这应该这样做
int countLines(const char *const filename)
{
int lines;
FILE *stream;
long int ignore;
stream = fopen(filename, "r");
if (stream == NULL)
return 0;
lines = 0;
while(fscanf(*stream, "%*s%ld", &ignore) == 1)
lines++;
fclose(stream);
return lines;
}
此
FILE *(*data);
Blackbox = LOAD(*data, lines);
也会导致问题,因为您正在取消引用data
但未分配。
你没有为结构数组分配空间,并且你分配了错误的ammount来复制字符串,在c中你总是需要比strlen()
返回的值多一个字符,因为你需要空间来存储'\0'
终结符。
以下函数修复了这两个问题,并且还以正确的方式使用fopen()
函数,请注意您不需要将FILE *
对象传递给函数,除非它之前已经打开过调用此函数,您还应该调用fclose()
struct _data *load(const char *const filename, int size)
{
struct _data *temp;
FILE *stream;
char c_temp[100];
long int l_temp;
int i;
stream = fopen(filename, "r")
if (stream == NULL)
return NULL;
temp = malloc(size * sizeof(*temp));
if (temp == NULL)
{
fclose(stream);
return NULL;
}
i = 0;
while ((fscanf(stream, "%99s%ld", c_temp, &l_temp) == 2) && (i < size))
{
size_t length;
length = strlen(c_temp);
temp[i].name = malloc(1 + length);
if (temp[i].name != NULL)
memcpy(temp[i].name, 1 + length);
temp[i].number = l_temp;
i++;
}
fclose(stream);
return temp;
}
程序的其余部分几乎没问题,您应该注意使其适用于这些修复所需的更改。