C:使用void指针数组

时间:2014-03-30 17:45:06

标签: c arrays pointers void-pointers

我是C的新手,在使用和理解指针时仍然很弱 - 尤其是void指针。我试图编写一个从文件加载数据并将这些数据存储在void指针数组中的函数,这样数组的每个元素都有(在本例中)文件该行的字符串。我怀疑代码有几个问题:

  1. 我不确定我是否正确使用* voidArray []作为函数的参数之一。
  2. 我不确定strcpy()是否是将行缓冲区的内容复制到相关数组元素中的好方法。
  3. 我不知道strcpy()目标的正确语法是什么(即void指针数组中的相关元素)。
  4. 也可能存在其他错误,但这些是我感到非常不确定的三个问题。

    这是我的功能:

    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;的错误有所了解,但我不知道自己应该做些什么。

2 个答案:

答案 0 :(得分:2)

我快速浏览了四个问题(除了我在评论中提到的问题):

  • 第一个是您注释掉了分配,所以如果在调用函数时未分配指针,您将写入内存中看似随机的位置。

  • 第二个是您在调用strcpy时使用取消引用运算符。例如,如果你有一个char指针数组,这将是一个char而不是一个指针。除此之外,您实际上无法取消引用void指针。

  • 第三个问题是你永远不会检查数组中的条目数,只是继续循环,读取和复制到数组中,而不考虑它的大小。

  • 第四个问题在于你调用这个函数的方式,你实际上没有传递一个指针数组,而是一个指针lines处的一个指针,它将超出限制数组。


作为一个不相关的附注:请记住,如果fgets读取换行符,则该换行符将位于缓冲区中。

答案 1 :(得分:-2)

您无法将内容存储在void指针中,也无法将其编入索引。除非先将它们强制转换,否则不能取消引用void指针。你不能用它们做指针运算。它们是泛型的语法糖,后来被添加,因为人们为此目的使用char *。