意外输出-在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);