意外输出-在c中存储到2D数组

意外输出-在c中存储到2D数组,c,C,我正在从许多文件中读取数据,每个文件都包含一个单词列表。我试图显示每个文件中的字数,但遇到了问题。例如,当我运行代码时,我收到如下所示的输出 除了两个文件外,几乎每个数量都能正确显示,每个文件都包含数千个字数。每一个文件只有三位数的单词,它们看起来很好 我只能猜测这个问题可能是什么(没有足够的空间分配到某处?),我不知道如何解决它。我很抱歉,如果这一切都是措词不当。我的大脑被炸了,我在挣扎。任何帮助都将不胜感激 我已经尽力使我的示例代码尽可能简短。我已经减少了很多错误检查和其他与完整程序相关的任

我正在从许多文件中读取数据,每个文件都包含一个单词列表。我试图显示每个文件中的字数,但遇到了问题。例如,当我运行代码时,我收到如下所示的输出

除了两个文件外,几乎每个数量都能正确显示,每个文件都包含数千个字数。每一个文件只有三位数的单词,它们看起来很好

我只能猜测这个问题可能是什么(没有足够的空间分配到某处?),我不知道如何解决它。我很抱歉,如果这一切都是措词不当。我的大脑被炸了,我在挣扎。任何帮助都将不胜感激

我已经尽力使我的示例代码尽可能简短。我已经减少了很多错误检查和其他与完整程序相关的任务。我还添加了我可以添加的评论。谢谢

停止词

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <stddef.h>
#include <string.h>

typedef struct
{
    char stopwords[2000][60];
    int wordcount;
} LangData;

typedef struct
{
    int languageCount;
    LangData languages[];
} AllData;


main(int argc, char **argv)
{
    //Initialize data structures and open path directory
    int langCount = 0;
    DIR *d;
    struct dirent *ep;
    d = opendir(argv[1]);

    //Count the number of language files in the directory
    while(readdir(d))
        langCount++;

    //Account for "." and ".." in directory
    //langCount = langCount - 2 THIS MAKES SENSE RIGHT?
    langCount = langCount + 1; //The program crashes if I don't do this, which doesn't make sense to me.

    //Allocate space in AllData for languageCount
    AllData *data = malloc(sizeof(AllData) + sizeof(LangData)*langCount); //Unsure? Seems to work.

    //Reset the directory in preparation for reading data
    rewinddir(d);

    //Copy all words into respective arrays.
    char word[60];
    int i = 0;
    int k = 0;
    int j = 0;
    while((ep = readdir(d)) != NULL) //Probably could've used for loops to make this cleaner. Oh well.
    {
        if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
        {
            //Filtering "." and ".."
        }
        else
        {
            FILE *entry;

            //Get string for path (i should make this a function)
            char fullpath[100];
            strcpy(fullpath, path);
            strcat(fullpath, "\\");
            strcat(fullpath, ep->d_name);

            entry = fopen(fullpath, "r");

            //Read all words from file
            while(fgets(word, 60, entry) != NULL)
            {
                j = 0;

                //Store each word one character at a time (better way?) 
                while(word[j] != '\0') //Check for end of word
                {
                    data->languages[i].stopwords[k][j] = word[j];
                    j++; //Move onto next character
                }
                k++; //Move onto next word
                data->languages[i].wordcount++;
            }

            //Display number of words in file
            printf("%d\n", data->languages[i].wordcount);
            i++; Increment index in preparation for next language file.

            fclose(entry);
        }
    }
}

这些文件有超过2000个单词吗?您只为2000个单词分配了空间,因此,一旦您的程序尝试复制word 2001,它将在为该数组分配的内存之外进行复制,可能会复制到为“wordcount”分配的空间中

我还想指出,fgets返回一个字符串到行尾,或者最多返回n个字符(本例中为60个字符),以先到者为准。如果您正在读取的文件中每行只有一个单词,那么这将很有效,否则必须在字符串中找到空格并从中计算单词数

如果您只是尝试获取字数,那么首先就不需要将所有字数存储在一个数组中。假设每行一个单词,以下内容也同样适用:

 char word[60];
 while(fgets(word, 60, entry) != NULL)
        {
            data->languages[i].wordcount++;
        }
fgets参考-

更新 我再看一眼,您可能希望尝试按如下方式分配数据:

typedef struct
{
    char stopwords[2000][60];
    int wordcount;
} LangData;

typedef struct
{
    int languageCount;
    LangData *languages;
} AllData;

AllData *data = malloc(sizeof(AllData));
data->languages = malloc(sizeof(LangData)*langCount);
这样,内存被专门分配给语言数组


我同意langCount=langCount-2是有道理的。出现了什么错误?

您是否验证了普通文本编辑器可以正确显示文件?也许是编码问题?是否所有单词都验证为小于60字节,包括换行符(请注意,我说的是“字节”而不是“字符”)?这都是假设文件已正确打开(
entry
不是
NULL
),因此字段已正确填充,而不是在调用
malloc()
时使用内存中的任何值对其进行初始化,因为
fgets()
循环将几乎被跳过(和
ferror(entry)
将返回一个非零值)。该文件可以在标准文本编辑器中打开。所有文件都是UTF-8格式。finnish.txt中最长的单词是“toimitusjohtaja”不接近60字节,但只是为了以防万一,我将其增加到200字节,并收到完全相同的输出。我插入了一行,在每次读取一个字时打印每个字,直到我按enter键,文件被正确读取到最后,但由于某种奇怪的原因,计数是错误的。文件中最大的字数是1337和文件每行只有一个字。我的程序还有更多的字需要存储(我需要稍后查找)。但是,我尝试将我可以存储的字数增加到4000个,字符数从60个增加到2000个,之前给我问题的两个字符现在都可以正确显示,但另一个是错误的。更新:我刚刚将每个字符的限制提高到10000个,说我做到了,现在所有字符都可以正确显示。这看起来很荒谬,也很有趣我不知道它为什么有效。
typedef struct
{
    char stopwords[2000][60];
    int wordcount;
} LangData;

typedef struct
{
    int languageCount;
    LangData *languages;
} AllData;

AllData *data = malloc(sizeof(AllData));
data->languages = malloc(sizeof(LangData)*langCount);