我正在尝试从文本文件中读取大量英文单词到字符串数组。单词数为2016415,单词的最大长度为69个字符。
如果我定义了像“char data [2016415] [70];”这样的数组,那么当我运行程序时会出现堆栈溢出。
所以我尝试使用calloc(),但是我无法理解我应该如何键入它以使它等同于“char data [2016415] [70];”。
以下程序在编译期间返回“传递`fgets'的arg 1从整数中生成指针而没有强制转换”警告。当我执行它时,它会出现“Exception:STATUS_ACCESS_VIOLATION”问题。
你能帮助我吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char *data; //data[2016415][70];
int i;
FILE *fsol;
fsol = fopen("C:\\Downloads\\abc\\sol2.txt","r");
data = (char*) calloc(2016415,70);
for(i=0;i<2016415;i++){
fgets(data[i] , 70 , fsol);
}
fclose(fsol);
return 0;
}
答案 0 :(得分:1)
好的,抱歉以前的建议。我忘了阵列是多么可怕。这个用10个单词的小数据集进行测试,但它应该扩展到你的单词数。请注意,fgets()似乎将行结尾作为前一个单词的一部分。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_CNT 2016415
#define MAX_WORD_LEN 70
int main(void)
{
char *data; //data[2016415][70];
int i;
FILE *fsol;
fsol = fopen("C:\\Downloads\\abc\\sol2.txt","r");
data = (char*) calloc(MAX_WORD_CNT, MAX_WORD_LEN);
// check for valid allocation
if (data == NULL)
{
return 1;
}
for(i=0; i<MAX_WORD_CNT; i++)
{
fgets(&data[i * MAX_WORD_LEN], MAX_WORD_LEN, fsol);
}
fclose(fsol);
return 0;
}
答案 1 :(得分:1)
calloc
只分配一大块内存 - 而不是指向其他数组的指针数组。
fgets
需要一个指向内存位置的指针,它应该将其转储到。
所以不要给它data[i]
的内容,而是要给它data[i]
的地址,以便它可以把它放在那里。
fgets(&data[i], 70, fsol);
您可能还需要调整循环,使其一次增加70多个字符,而不是一个。
答案 2 :(得分:0)
这是我如何分配数组
char **data = malloc(MAX_WORD_CNT * sizeof(char *));
for(int i = 0; i < MAX_WORD_CNT; i++)
data[i] = malloc(MAX_WORD_LEN);
你可能想为malloc添加一些错误检查。
答案 3 :(得分:0)
data
是一个指向char的指针(也可以作为char数组寻址),因此data[i]
是一个char。 fgets
需要一个指向char的指针,但是你传递了一个char;这就是你收到警告的原因,你试图使用char(整数)作为指针。
当你运行程序时,它接受单个char参数并将其解释为指向char的指针,因此访问冲突因为该char的值不是有效地址。
因此,在循环中,您应该将fgets
指针传递给data
,并在每次迭代时将其递增70。您可以使用“指向数组元素的指针”形式&data[i]
并将i或简单指针形式与最初设置为data
的另一个指针变量一起递增,并自行递增。
答案 4 :(得分:0)
答案很简单:你不要施展它。投射malloc
/ calloc
/等的结果。没有任何目的,但如果忘记包含stdlib.h
,可能会产生隐藏主要错误的副作用。这些分配函数的返回类型(void *
)将自动转换为您需要的任何内容。
如果您真的想知道类型,那就是(char (*)[70])
。但请不要通过写这个来实际模糊你的程序。 (除非你实际上是在编写C ++,在这种情况下你应该标记你的问题C ++而不是C,或者更好地使用new
。)