C:使用空指针数组

C:使用空指针数组,c,arrays,pointers,void-pointers,C,Arrays,Pointers,Void Pointers,我是C语言的新手,在使用和理解指针(尤其是空指针)方面仍然很薄弱。我试图编写一个函数,从文件中加载数据并将这些数据存储在一个空指针数组中,这样数组的每个元素(在本例中)都有来自该文件行的字符串。我怀疑代码有几个问题: 我不确定是否正确使用*voidArray[]作为函数的参数之一 我不确定strcpy()是否是将行缓冲区的内容复制到相关数组元素的好方法 我不知道strcpy()的目标(即void指针数组中的相关元素)的正确语法是什么 可能还有其他错误,但这是我感到非常不确定的三个问题 以下是我的

我是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*
    很容易,只有两个