我是C的新手,在使用和理解指针时仍然很弱 - 尤其是void指针。我试图编写一个从文件加载数据并将这些数据存储在void指针数组中的函数,这样数组的每个元素都有(在本例中)文件该行的字符串。我怀疑代码有几个问题:
也可能存在其他错误,但这些是我感到非常不确定的三个问题。
这是我的功能:
void *readData(void *voidArray[], const char *filename, int lines) {
FILE *stream = fopen(filename, "r");
if (stream == NULL) {
perror("Error loading file");
return 1;
}
char lineBuffer[BUFFER_SIZE];
int i = 0;
while(!feof(stream)) {
while(fgets(lineBuffer, sizeof(lineBuffer), stream)) {
// *voidArray[i] = malloc(strlen(lineBuffer) + 1); // probably not what I want
strcpy(*voidArray[i], lineBuffer);
i++;
}
}
fclose(stream);
}
...这里是main()的开头,其中(再次)我不确定用于声明(和初始化?)数组的正确语法是什么:
int main(void)
{
int lines = 20;
void *varray[lines];
// varray = malloc(sizeof(char *) * lines); // probably not what I want
readData(varray[lines], FILENAME, lines); // FILENAME declared earlier
一些建议的代码修复将非常受欢迎(特别是如果我完全错过了更合适的方法),但我觉得我需要更多的是为什么建议是正确的。如果我可以解决这个问题,我想 - 在最坏的情况下 - 我会很清楚自己需要自学的东西:指针。提前感谢您的任何帮助或评论,以及您对此阅读的耐心。
编辑:Joachim Pileborg的答案有所帮助,但我仍然缺少一些基本的(可能很明显)。这是我修改过的功能:
void *loadData(void *voidArray, const char *filename, int lines) {
FILE *stream = fopen(filename, "r");
if (stream == NULL) {
perror("Error loading file");
}
char lineBuffer[BUFFER_SIZE];
int i = 0;
while(fgets(lineBuffer, sizeof(lineBuffer), stream)) {
strcpy((voidArray+i), lineBuffer);
printf("voidArray: %s\n", (char *)(voidArray+i));
i++;
}
for (i = 0; i < lines; i++) {
printf("array element %d: %s\n", i, (char *)(voidArray+i));
}
fclose(stream);
}
以下是我的两项测试的结果:
voidArray: Good
voidArray: morning
voidArray: everyone
array element 0: Gmeveryone
array element 1: meveryone
array element 2: everyone
同样,我可能会遗漏一些微不足道的东西。我想要做的是让varray由void指针组成,每个指针都指向一个从外部文件读取的对象(例如,一个字符串)。我对&#34; varray + i&#34;的错误有所了解,但我不知道自己应该做些什么。
答案 0 :(得分:2)
我快速浏览了四个问题(除了我在评论中提到的问题):
第一个是您注释掉了分配,所以如果在调用函数时未分配指针,您将写入内存中看似随机的位置。
第二个是您在调用strcpy
时使用取消引用运算符。例如,如果你有一个char
指针数组,这将是一个char
而不是一个指针。除此之外,您实际上无法取消引用void
指针。
第三个问题是你永远不会检查数组中的条目数,只是继续循环,读取和复制到数组中,而不考虑它的大小。
第四个问题在于你调用这个函数的方式,你实际上没有传递一个指针数组,而是一个指针lines
处的一个指针,它将超出限制数组。
作为一个不相关的附注:请记住,如果fgets
读取换行符,则该换行符将位于缓冲区中。
答案 1 :(得分:-2)
您无法将内容存储在void指针中,也无法将其编入索引。除非先将它们强制转换,否则不能取消引用void指针。你不能用它们做指针运算。它们是泛型的语法糖,后来被添加,因为人们为此目的使用char *。