经过几次迭代后,fgetws会出现段错误

时间:2015-03-01 03:00:37

标签: c

我正在尝试创建一个包含日语字母的容器,所以我使用数据类型wchar_t,并使用UTF-8编码我的.c和.txt文件。这个想法是程序通过读取.txt文件来填充容器。我可以在前几行阅读,但经过几次迭代后,程序会出现段错误。我怀疑它是fgetws,因为我已经在函数中添加了一些wprintf语句。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <locale.h>

typedef struct entry {
    wchar_t romaji[5];
} entry;

typedef struct dictionary {
    struct entry entry[46];
} dictionary;

void init_dictionary(dictionary **dictionary) {
    (*dictionary) = malloc(sizeof(dictionary));
}

void add_romaji(dictionary *dictionary, wchar_t *romaji, int index) {
    entry new;

    wcscpy(new.romaji, romaji);

    dictionary->entry[index] = new;
}

void populate(dictionary *dictionary) {
    FILE *fp;
    wchar_t line[5];
    wchar_t *ptr;
    wchar_t romaji[5];
    int i;

    fp = fopen("romaji.txt", "r");
    i = 0;

    while(fgetws(line, 5, fp) != NULL) {
        wcstok(line, L"\n", &ptr);
        wcscpy(romaji, line);
        add_romaji(dictionary, romaji, i);
        ++i;
    }

    fclose(fp);
}

int main(int argc, char ** argv) {
    setlocale(LC_CTYPE, "");

    dictionary *dictionary;

    init_dictionary(&dictionary);
    populate(dictionary);

    return EXIT_SUCCESS;
}

romaji.txt是UTF-8,只包含日语字母表中每个字符的一行。我无法在这里找到缩进工作,所以我无法发布,抱歉。我试着寻找答案,但没有人帮忙。如果有人能让我知道我的错误是什么,我将不胜感激。

1 个答案:

答案 0 :(得分:3)

不加选择地使用typedef并命名变量与结果类型相同的经典问题。

您需要更改:

(*dictionary) = malloc(sizeof(dictionary));

为:

*dictionary = malloc(sizeof(struct dictionary));

甚至更好,将整个功能更改为:

void init_dictionary(struct dictionary ** dict)
{
    struct dictionary * new_dict = malloc(sizeof *new_dict);
    if ( !new_dict ) {
        perror("couldn't allocate memory");
        exit(EXIT_FAILURE);
    }
    *dict = new_dict;
}

现在,您只是为指向struct dictionary的指针分配内存,而不是为实际的struct dictionary,并且您可以从任何未定义的行为中分析内存分配正在引导你。更有可能的是它践踏fopen()动态分配的内存,覆盖文件指针指向的内容并导致fgetws()调用中的段错误。

typedef具有有效用途,但只保存一些按键不是其中之一,并且通常不会导致这样的混乱。省去一些麻烦,只需完整地编写struct类型。