1

对 C 语言仍然很陌生,但开始掌握它的窍门....

我的程序应该创建/写入文件并存储来自结构数组的信息。那部分很好。我遇到的问题是从该文件读回一个空的结构数组......

这是我的结构:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX 100

struct Video { 
char name[1024];                //name
int ranking;                // Number of viewer hits
char url[1024];             // YouTube URL
};

struct Video Collection[MAX];

这是我的加载方法,它从我的文件读回我的结构数组:

void load()
{
FILE *fileName;
fileName = fopen("ranking.dbm", "rb");
if (fileName != NULL){
    fread (Collection,1,1,fileName);
}
else {
    printf("ERROR");
}   

}

这也是我的写方法:

void save()
{
FILE * pFile;
pFile = fopen ( "Ranking.dbm" , "wb" );
fwrite (Collection, 1 , sizeof(Collection), pFile );
fclose (pFile); 
}

但是,当我在加载后打印出我的数组时collection......它是空的......即使我可以在项目文件夹中看到我的文件并打开它并验证数据是否在那里......

我是否正确地认为我不需要缓冲区,因为在使用它之前我不需要对其进行任何处理?

也因为我已经为内存静态分配了空间......我认为我可以直接读入数组是否正确?

这是我的打印代码:

void printall()
{
int i; 

printf("\nCollections: \n"); 

for(i = 0; i < tail; i++)
{
    printf("\nVideo Name: %s", Collection[i].name);
    printf("\nRanking (Hits): %d", Collection[i].ranking);
    printf("\nURL: %s", Collection[i].url);
    printf("\n");
}
}
4

3 回答 3

4

fread实际上旨在从文件中读取结构数组,但您必须正确使用它。

fread的四个参数如下:

void * ptr, size_t size, size_t count, FILE * stream

第一个参数是放置数据的位置(在您的情况下为Collection)。第二个参数是每个数组元素的大小:在你的情况下,你想把sizeof(struct Video). 第三个参数是您要读取的元素数,在您的情况下是MAX. 第四个参数是要读取的文件。

如果你想读入一个类似的数组struct Video Collection[MAX],你会使用fread(Collection, sizeof(struct Video), MAX, file). fread将返回读取的元素总数,即 ≤ MAX

于 2012-09-29T18:26:33.913 回答
2

我在这里看到了一些问题..首先你是如何阅读文件的:

fread (Collection,1,1,fileName); 

这将读入集合 1 个字节,fileNameCollection
应该检查 的返回状态fread(),当它成功时,它会告诉您要读取的字节总数。(参数 2 * 参数 3,在您的情况下为 1*1)。

当我像这样修改您的阅读代码时:

fread(Collection, sizeof(struct Video), 1, fileName);

它确实成功地从文件中读取......但是你现在有一个不同的问题。假设您的文件包含以下内容:

something 5 http://something.com
nothing 3 http://nothing.com

所以(我认为)这是您文件的格式,名称(ASCII),排名(int)和URL(ASCII)。现在假设您的main()函数如下所示:

int main ()
{
    load();
    printall();
    return 0;
}

你会得到类似的stdout东西:

Collections:

Video Name: something 6 http://something.com
nothing 3 http://nothing.com
Ranking (Hits): 0
URL: 

原因是你用静态(和非常大的)元素声明了你的数组。将fread()尝试读取sizeof(struct Video)1024+4+1024 字节,因此除非您的每一行都是精确大小(名称和 url 为 1024 个字符),否则您将得到看起来混乱或空数据的内容.

我建议您阅读,直到您点击一个空格并将每个值存储在正确的元素中,而不是尝试将整个文件读出到数组中。

编辑:
如果你想填充你的数组,如:

fread(myarray, sizeofstruct, numberofstructs, file);

您必须保证数据长度。在您的示例中,您必须说“名称是许多字符,+ 空格 = 1024”,对于 URL 也是如此。这似乎是一个可怕的空间浪费。更好的选择是一次填充一个元素:

for(0 to last_element){
  set myarray.name = data until first space
  set myarray.ranking = (int)data until second space
  set myarray.url = data until newline
}

您可以使用fscanf()to 读取直到出现空格。坦率地说,如果您要一次填充一个元素,我只需将字符指针用于名称和 url 并动态分配内存,这样您就不会浪费大量的数组。

于 2012-09-29T19:27:04.470 回答
1

首先我必须假设你的意思struct Video Collection[MAX];是你的上半部分是无效的 C.

第二:您正在将 1 个字节读入 Collection。

尝试 fread(Collection, sizeof(struct Video), MAX, fileName);

这将最多将字节MAX块读取到 Collection 中。sizeof(struct Video)

于 2012-09-29T18:26:23.587 回答