C:使用空指针数组
我是C语言的新手,在使用和理解指针(尤其是空指针)方面仍然很薄弱。我试图编写一个函数,从文件中加载数据并将这些数据存储在一个空指针数组中,这样数组的每个元素(在本例中)都有来自该文件行的字符串。我怀疑代码有几个问题:C:使用空指针数组,c,arrays,pointers,void-pointers,C,Arrays,Pointers,Void Pointers,我是C语言的新手,在使用和理解指针(尤其是空指针)方面仍然很薄弱。我试图编写一个函数,从文件中加载数据并将这些数据存储在一个空指针数组中,这样数组的每个元素(在本例中)都有来自该文件行的字符串。我怀疑代码有几个问题: 我不确定是否正确使用*voidArray[]作为函数的参数之一 我不确定strcpy()是否是将行缓冲区的内容复制到相关数组元素的好方法 我不知道strcpy()的目标(即void指针数组中的相关元素)的正确语法是什么 可能还有其他错误,但这是我感到非常不确定的三个问题 以下是我的
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);
}
void*readData(void*voidArray[],常量字符*文件名,整数行){
文件*stream=fopen(文件名,“r”);
if(流==NULL){
perror(“加载文件时出错”);
返回1;
}
char lineBuffer[缓冲区大小];
int i=0;
而(!feof(stream)){
while(fgets(lineBuffer、sizeof(lineBuffer)、stream)){
//*voidArray[i]=malloc(strlen(lineBuffer)+1);//可能不是我想要的
strcpy(*voidArray[i],lineBuffer);
i++;
}
}
fclose(流);
}
…这里是main()的开头,其中(再次)我不确定声明(和初始化)数组的正确语法是什么:
int main(无效)
{
整数行=20;
void*varray[行];
//varray=malloc(sizeof(char*)*行);//可能不是我想要的
readData(varray[lines],FILENAME,lines);//前面声明的文件名
一些建议的代码修复将非常感谢(特别是如果我完全没有找到更合适的方法),但我觉得我更需要的是一个很好的解释,解释为什么这些建议是正确的。如果我能围绕这个问题思考,我想——最坏的情况是——我会很清楚我还需要教自己什么:指针。提前感谢你的任何帮助或评论,以及你耐心地阅读到目前为止。
编辑: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);
}
同样,我可能遗漏了一些琐碎的东西。我想做的是让varray由void指针组成,每个指针指向从外部文件读取的对象(例如,一个字符串)。我知道“varray+I”的错误之处,但我不知道我实际上应该做什么。你不能将内容存储在空指针中,也不能索引到它们中。除非先强制转换空指针,否则不能取消对空指针的引用。你不能对它们进行指针算术。它们是泛型的语法糖,后来才添加,因为人们为了这个目的使用了char*se.我一眼就能看到四个问题(除了我在评论中提到的问题外):
- 第一个是您注释掉了分配,因此,如果在调用函数时没有分配指针,您将写入内存中看似随机的位置
- 第二种方法是在调用strcpy时使用dereference操作符。例如,如果您有一个
指针数组,这将是一个char
而不是一个指针。此外,您实际上不能对char
指针进行去引用void
- 第三个问题是,您从不检查数组中的条目数,您只是不断循环、读取和复制到数组中,而不考虑数组的大小
- 第四个问题是调用此函数的方式,实际上不是传递指针数组,而是在索引
上传递一个指针,这将超出数组的限制行
作为一个不相关的旁注:请记住,如果读取一个换行符,那么该换行符将在缓冲区中。您不需要外部循环(
while(!feof(…))
loop).事实上,如果在到达文件末尾之前读取文件时出错,则可能会导致无限循环。如果存储字符,为什么不使用字符数组和字符指针?你不需要使用void啊,我认为关于外部循环的冗余,你是对的。谢谢!读取我为测试创建的任何文件都没有错误,将文件行读入缓冲区是这个函数的少数几个方面之一,我确信它能按预期工作。Buella Gabor-我希望能够根据文件存储int或double(显然,我需要相应地调整数据读取函数).为了缩短我给出的代码量,我只使用了chars。在最初的示例中,您需要voidArray[I]=malloc(strlen(X)+1);strcpy(voidArray[I],X);
。您可以使用readData(varray,FILENAME,line)调用它
。这很好。修订版没有意义。因为您只传入一个缓冲区,但似乎要在其中存储多个字符串。您看到的是复制字符串的结果,每次都从同一缓冲区中的一个位置开始,这就是修订版所做的。void*x;*x=5;
是非法的,这就是我的意思。相比之下,int*x;*x=5;
是合法的谢谢你,v3ga!我真的希望能把它绑定到一个快速排序中。如果我放弃这个函数,在使用(例如)字符指针的同时在main()中写入所有内容,我可以让事情顺利进行。所以我的下一步(我希望如此)似乎理解了void指针及其正确的语法和逻辑。@jda:void*
很容易,只有两个