【发布时间】:2023-03-04 05:31:01
【问题描述】:
我是 C 的新手,但在使用和理解指针方面仍然很薄弱——尤其是 void 指针。我正在尝试编写一个从文件加载数据并将这些数据存储在 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”时做错了什么,但我不知道我实际上应该做什么。
【问题讨论】:
-
您不需要外部循环(
while (!feof(...))循环)。实际上,如果在到达文件末尾之前读取文件有错误,它可能会导致无限循环。 -
如果你存储字符,为什么不直接使用字符数组、字符指针呢?你不需要为此做空
-
啊,我认为您对外部循环的冗余是正确的。谢谢!读取我为测试创建的任何文件都没有错误,将文件行读入缓冲区是我确信该功能按预期工作的少数几个方面之一。
-
Buella Gabor - 我还希望能够存储整数或双精度数,具体取决于文件(显然我需要相应地调整数据读取功能)。为了缩短我提供的代码量,我只使用了字符的大小写。
-
在原版中,您需要
voidArray[i] = malloc( strlen(X) + 1 ); strcpy( voidArray[i], X);。你用readData(varray, FILENAME, lines);调用它。那很好。修改后的版本没有意义。因为您只传入一个缓冲区,但您似乎想在其中存储多个字符串。您看到的是在彼此顶部复制字符串的结果,每次在同一缓冲区中稍后从一个位置开始,这就是您的修订版本所做的。
标签: c arrays pointers void-pointers