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");
}
}

コレクションをファイルに保存するコードを記述し、同様にファイルをロードしてそこから読み取るコードを記述したいと思います。

かなり役に立った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(): ");
                        }   

                    }

今、これを読んだ人はおそらくすでに手のひらに直面していると確信していますが、私はそうではありません。コードは書き込むファイルを作成せず、同様に読み取るファイルもないため、何が問題なのかを確認することすらできません。今、私は与えられた答えを探していませんが、私はそれが間違って何をしているのか、私が理解していないように見える概念、そしてこれらを修正する方法を本当に知りたいです。私はすでにこれについて数時間の研究をしていて、それが初歩的なものであることに気づいていますが、私は本当に学びたいと思っています。教授が言ったトピックにそのイライラする時間を費やすのは、せいぜい数時間しかかからないはずだと言った。

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);

freadそしてもちろん、メソッド内の対応する呼び出しread

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 に答える