读取文件时的细分故障



我仍然是C语言的新手,我是第一次玩阅读文件。我的代码与以前的代码相似,该代码过去可以很好地运行,但是现在我遇到了问题。每次尝试运行此程序时,我都会不断收到错误Segmentation fault (core dumped)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct student {
    char first[30];
    char last[30];
    char ssn[9];
};
void make_arrays() {
    FILE *fp = fopen("students.db", "r");
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    long num_students = size / sizeof(struct student);
    printf("There are %ld students in the file", num_students);
    fclose(fp);
}
int main(int argc, char **argv[]) {
    make_arrays();
    return 0;
}

分割故障可能是由fopen未能打开文件引起的。

您应始终测试此类故障并通过信息丰富的消息退出。

还要注意,如果文件确实是二进制文件,则应在二进制模式下打开,以避免线翻译结束:

FILE *fp = fopen("students.db", "rb");

还将main的原型更改为int main(int argc, char *argv[])int main()char **argv[]中的星星太多。

您不必将我的答案标记为接受,只是想激发人们编写代码,以便它可以阅读和安全。不要懒于在质量上写这样的代码。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
struct student /* Magic numbers everywhere */
{
    char first[30];
    char last[30];
    char ssn[9];
};


void* handle_nullptr_error (void* ptr, char *action, int code)
{
    if(ptr == NULL)
    {
        fprintf(stderr, "Failed to %sn", action);
        exit(code);
    }
    printf("Succeeded to %sn", action);
    return ptr;
}
int handle_nonzero_error (int val, char *action, int code)
{
    if(val != 0)
    {
        fprintf(stderr, "Failed to %sn", action);
        exit(code);
    }
    printf("Succeeded to %sn", action);
    return val;
}
int handle_negval_error (int val, char *action, int code)
{
    if(val < 0)
    {
        fprintf(stderr, "Failed to %sn", action);
        exit(code);
    }
    printf("Succeeded to %sn", action);
    return val;
}


/** This function is not guaranteed to be portable and work (but it will at least fail properly),
 * because not all systems and/or library implementations support `SEEK_END` in files
 * opened in text mode, as specified by @mode
 * Moreover, in binary mode it will behave in an undefined manner, because different systems
 * may store files data completely differently. In most cases it will succeed, just don't
 * write code that crashes if not.
 */
long int get_file_charcount (const char *filename, char* mode)
{
    FILE*       fp      = NULL;
    long int    fpSize  = 0L;
    /* Alignment for complicated function calls (for e.g where functions are passed as arguments) */
    fp = handle_nullptr_error       (fopen(filename, mode),     "open file.",           1);
    (void)handle_nonzero_error      (fseek(fp, 0, SEEK_END),    "seek end position.",   2);
    fpSize = handle_negval_error    (ftell(fp),                 "tell position.",       3);
    fclose(fp); /* - May fail, as well */
    return fpSize;
}
/** This function depends on POSIX headers and it is unix-conformant, although there are still
 * some exceptions.
 *
 * Note that the value returned is the length of the contents of the symbolic link,
 * and does not count any trailing null pads. The value is ought to be system-specific.
 */
_off64_t get_file_size (const char *filename)
{
    struct stat st = {0};
    (void)handle_negval_error(stat(filename, &st), "get file size.", (-1));
    return st.st_size;
}
/** A validation function should first determine whether file's size is
 * actually dividable by `sizeof(struct STUDENT_DESCRIPTION);`.
 *
 * Further more you can use `get_file_size()` as an alternative to
 * `get_file_charcount()`. In the latter case, make sure you to specify the
 * appropriate mode, "r" for text files and "rb" for binary files.
 */
void make_arrays ()
{
    long int    size            = get_file_charcount("myfile.txt", "r");
    long int    num_students    = size / sizeof(struct STUDENT_DESCRIPTION);
    printf("size of file: %ldn", size);
    printf("There are %ld students in the file", num_students);
}


int main (void)
{
    make_arrays();
    return EXIT_SUCCESS;
}

相关内容

  • 没有找到相关文章

最新更新