0

我正在慢慢学习 C,但不是很好。我一直在阅读无数关于阅读和写作的主题和问题,但我还没有找到任何能让这一切都为我所用的东西。

我得到了以下代码:

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

#define MAX 100

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

struct YouTubeVideo Collection[MAX];

int tail = 0;

//-- Forward Declaration --// 
void printall();
void insertion();
void branching(char option);
void menu(); 


int main()
{
char ch; 

// TODO: Add code to load save data from file

printf("\n\nWelcome to CSE240: YouTube Classic Hits\n");

do {
     menu();
     fflush(stdin);           // Flush the standard input buffer 
     ch = tolower(getchar()); // read a char, convert to lower case
     branching(ch);
} while (ch != 'q');

return 0; 
}

void menu()
{
printf("\nMenu Options\n");
printf("------------------------------------------------------\n");
printf("i: Insert a new favorite\n");
printf("p: Review your list\n"); 
printf("q: Save and quit\n");
printf("\n\nPlease enter a choice (i, p, or q) ---> "); 
}

void branching(char option)
{
switch(option)
{
    case 'i':
        insertion();
    break;

    case 'p':
        printall();
    break;

    case 'q':
        // TODO: Add code to save data into a file
    break;

    default:
        printf("\nError: Invalid Input.  Please try again..."); 
    break;
}
}

void insertion()
{
if(tail < MAX)
{
    printf("\nWhat is the name of the video? (No spaces characters allowed)\n");
    scanf("%s", Collection[tail].video_name);

    printf("\nHow many viewer hits does this video have?\n");
    scanf("%d", &Collection[tail].ranking);

    printf("\nPlease enter the URL: ");
    scanf("%s", &Collection[tail].url);

    tail++;
}
else
{
    printf("\nERROR: Your collection is full. Cannot add new entries.\n");
}
}

void printall()
{
int i; 

printf("\nCollections: \n"); 

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

我想编写将集合存储到文件中的代码,同样正确地编写将加载文件并从中读取的代码。

感谢一位相当有帮助的助教,我能够为每个人制定以下代码

void store()
{
FILE * fileName;
fileName = fopen ( "Ranking.dbm" , "wb" );
fwrite ( Collection, sizeof(struct YouTubeVideo), MAX, fileName);

fclose (fileName);
                    }

void read()
{
FILE *fileName;
fileName = fopen("ranking.dbm", "rb");
if (fileName != NULL){
    fread ( Collection, sizeof(struct YouTubeVideo), MAX, fileName);
}
else {
    printf("ERROR");
                        }   

                    }

我相信这些都可以发挥作用,但真正的问题是我认为我不太了解它们是如何工作的,而且我相信由于我什至不知道它们是如何工作的,所以我不知道如何在代码中使用它们。

我将这两种方法都添加到给定的代码中并想出了这个:

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

#define MAX 100

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

struct YouTubeVideo Collection[MAX];

int tail = 0;

//-- Forward Declaration --//
void printall();
void insertion();
void branching(char option);
void menu();
void store();
void read();


int main()
{
char ch;

read();

printf("\n\nWelcome to CSE240: YouTube Classic Hits\n");

do {
    menu();
    fpurge(stdin);            // Flush the standard input buffer
    ch = tolower(getchar()); // read a char, convert to lower case
    branching(ch);
} while (ch != 'q');

return 0;
}

void menu()
{
printf("\nMenu Options\n");
printf("------------------------------------------------------\n");
printf("i: Insert a new favorite\n");
printf("p: Review your list\n");
printf("q: Save and quit\n");
printf("\n\nPlease enter a choice (i, p, or q) ---> ");
}

void branching(char option)
{

switch(option)
{
    case 'i':
        insertion();
        break;

    case 'p':
        printall();
        break;

    case 'q':
        store();
        break;


    default:
        printf("\nError: Invalid Input.  Please try again...");
        break;
}
}

void insertion()
{
if(tail < MAX)
{
    printf("\nWhat is the name of the video? (No spaces characters allowed)\n");
    scanf("%s", Collection[tail].video_name);

    printf("\nHow many viewer hits does this video have?\n");
    scanf("%d", &Collection[tail].ranking);

    printf("\nPlease enter the URL: ");
    scanf("%s", &Collection[tail].url);

    tail++;
}
else
{
    printf("\nERROR: Your collection is full. Cannot add new entries.\n");
}
}

void printall()
{
int i;

printf("\nCollections: \n");

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

}

void store()
{
FILE * fileName;
fileName = fopen ( "Ranking.dbm" , "wb" );
if (fileName != NULL)
    {
        fwrite ( Collection, sizeof(struct YouTubeVideo), MAX, fileName);
        fclose (fileName);
    }

else {
    perror("Following error occurred(): ");
}
                    }



void read()
{
FILE *fileName;
fileName = fopen("Ranking.dbm", "rb");
if (fileName != NULL)
    {
        fread ( Collection, sizeof(struct YouTubeVideo), MAX, fileName);
        fclose(fileName);
    }

else {
    perror("Following error occurred with fopen(): ");
                        }   

                    }

现在我确信任何读过这篇文章的人可能已经因为他们看到了问题而面对手掌,但我没有。该代码不会创建要写入的文件,同样它也没有可读取的内容,所以我什至无法开始看到它有什么问题。现在我不是在寻找一个给定的答案,但我真的很想知道我做错了什么,我似乎不理解哪些概念,以及如何解决这些问题。我已经对此进行了几个小时的研究,我意识到这是初级的,但我真的很想学习。在教授说最多只需要几个小时即可完成的主题上花费数小时令人沮丧。

4

3 回答 3

2

fopen()你真的应该检查反对的返回值NULL- 如果打开文件有问题,它将返回NULL并设置errno. 这可能是一个权限错误,通过检查返回值并在设置了错误时打印错误,您将获得有关问题所在的更多信息。

于 2012-10-01T04:41:18.540 回答
0

我相信你可能对read函数有问题,它没有调用fclose文件句柄(顺便说一句,调用它fileName有点误导)。

因为您将文件保持打开状态,所以当您最终调用store. 如果无法在该函数中打开文件,您还没有输出任何错误消息,因此很容易被忽视……至少在您想知道为什么您的文件日期没有改变之前。

否则代码看起来没问题。它所做的只是将数组的全部内容转储出内存并再次读回。您可能还需要写出 的值tail,因为它会跟踪您保留的元素数量。因此,只需进行最少的代码更改,请执行以下操作:

fwrite ( &tail, sizeof(int), 1, fileName);
fwrite ( Collection, sizeof(struct YouTubeVideo), MAX, fileName);

当然还有freadread方法中的相应调用。

fread ( &tail, sizeof(int), 1, fileName);
fread ( Collection, sizeof(struct YouTubeVideo), MAX, fileName);

重申:不要忘记关闭您的文件!!!!

fclose(fileName);
于 2012-10-01T04:53:35.727 回答
0

次要:确保更频繁地检查 fopen、fread、fwrite 等内容的返回值。

轻度:文件名中可能存在拼写错误(某些操作系统的文件名区分大小写)

严重:read() 没有为 tail 设置值... :)

于 2012-10-01T04:54:53.290 回答