我是 C 语言的新手,在使用和理解指针(尤其是 void 指针)方面仍然很薄弱。我正在尝试编写一个从文件加载数据并将这些数据存储在空指针数组中的函数,这样数组的每个元素(在本例中)都具有来自文件该行的字符串。我怀疑代码有几个问题:
- 我不确定我是否正确使用 *voidArray[] 作为函数的参数之一。
- 我不确定 strcpy() 是否是将行缓冲区的内容复制到相关数组元素的好方法。
- 我不知道 strcpy() 的目标(即 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 指针组成,每个指针指向一个从外部文件读取的对象(对于本例,一个字符串)。我知道我在使用“varray+i”做错了什么,但我不知道我实际上应该做什么。
最佳答案
我一眼就看出了四个问题(除了我在评论中提到的那个):
首先是您注释掉了分配,因此如果在调用函数时未分配指针,您将写入内存中看似随机的位置。
第二个是您在调用
strcpy
时使用取消引用运算符。例如,如果您有一个char
指针数组,这将是单个char
而不是指针。除此之外,您实际上无法取消引用void
指针。第三个问题是您从不检查数组中的条目数,您只是不断循环读取并复制到数组中而不考虑其大小。
第四个问题是你调用这个函数的方式,你实际上不是在传递一个指针数组,而是在索引
lines
处传递一个指针,这将是一个超出数组的限制。
作为一个不相关的旁注:记住如果 fgets
读取换行符,然后该换行符将在缓冲区中。
关于C:使用空指针数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22747461/