在C中读取和写入文件

时间:2012-10-01 04:37:45

标签: c

我正在慢慢学习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");
}
}

我想编写将集合存储到文件中的代码,以及将加载文件并从中读取的代码。

感谢TA非常有帮助,我能够为每个

制定以下代码
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(): ");
                        }   

                    }

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

我相信你可能会遇到read函数的问题,它不会在文件句柄上调用fclose(顺便说一下,调用它fileName有点误导)。

因为您将文件保持打开状态,所以当您最终调用store时,您很可能无法覆盖该文件。如果无法在该功能中打开文件,则您没有输出任何错误消息,因此很容易在雷达下滑动......至少在您想知道为什么您的文件日期不会改变之前。

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

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

当然,您fread方法中对read的相应调用。

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

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

fclose(fileName);

答案 2 :(得分:0)

轻微:确保更频繁地检查诸如fopen,fread,fwrite等的返回值。

温和:你的文件名中有一个潜在的拼写错误(某些操作系统有区分大小写的文件名)

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