简体   繁体   English

在结构数组中搜索名称时出现段错误

[英]Seg fault while searching through struct array for names

I am writing a program that is supposed to look through a file load it up and you are supposed to search for a name in the list using the command ./main (searchedname) after compilation. 我正在编写一个程序,该程序应该查看文件并将其加载,并且应该在编译后使用命令./main(searchedname)在列表中搜索名称。 While compiling I get no errors. 编译时我没有错误。 But when I try to search for a name I get a segfault immediately and the program terminates. 但是,当我尝试搜索名称时,我会立即遇到段错误,程序会终止。 Here is my code. 这是我的代码。

#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);
    }
}

The file looks like this 该文件看起来像这样

foo 7894898,
bar 7895497
.
.
.

The reason is that you are not allocating space for your array, but you have many other minor issues that would make your program have weird behavior. 原因是您没有为数组分配空间,但是还有许多其他小问题,这些问题会使您的程序出现奇怪的行为。

  1. You don't check that the file opened, after every call to fopen() you need to make sure that the returned value is not NULL . 您无需检查文件是否已打开,在每次调用fopen()您需要确保返回的值不是NULL

     FILE *stream = fopen(filename, "r"); if (stream == NULL) /* do not try to read from stream */ 
  2. while(!feof(file)) is always wrong and you pass the wrong value to feof() anyway, to count the number of valid lines in the file, this should do it 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; } 
  3. This 这个

     FILE *(*data); Blackbox = LOAD(*data, lines); 

    would also cause problems, because you are dereferencing data but it's not allocated. 也会引起问题,因为您正在取消引用data但未分配数据。

  4. You didn't allocate space for the array of structs, and you allocated the wrong ammount to copy the string, in c you always need one character more than the value returned by strlen() , because you need space to store the '\\0' terminator. 您没有为结构数组分配空间,并且分配了错误的数量来复制字符串,在c中,您总是需要比strlen()返回的值多一个字符,因为您需要空间来存储'\\0'终止。

    The following function fixes boths issues, and also uses the fopen() function in the correct way, note that you don't need to pass the FILE * object to the function unless it was already opened before calling this function, and you should also call fclose() 以下函数可以解决这两个问题,并且还可以以正确的方式使用fopen()函数,请注意,除非在调用此函数之前已将FILE *对象打开,否则您无需将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; } 

The rest of the program is almost ok, you should note what changes it will require to make it work with these fixes. 该程序的其余部分几乎都可以,您应该注意要使其与这些修补程序一起使用需要进行哪些更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM