【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.19591

自己参照構造体内のリスト参照の仕方
投稿者---Kei(2005/01/27 17:37:10)


いつもお世話になっています。
フォルダ中にあるファイルの一覧を出し、
一覧にあるファイルを選び編集と言うのをやっています。
No1.sample1.txt
No2.sample2.txt
No3.sample3.txt
No4.sample4.txt
↑のようなソートして表示させるまでは出来たのですが、
表示させているNoをscanfで画面から入力し、
例)1と入力したらsample1.txtをオープンして書き込み処理が出来る
そのファイルにアクセスするような事は可能でしょうか?
また、可能の場合どのようにすれば出来るか教えてください。

フルパス指定でならファイルオープンして書き込む事は出来たのですが
Noからファイルパスを引っ張って参照する方法が分かりません。

過去ログにもなかったようなのでよろしくお願いします。
検索漏れであったらすみません。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:自己参照構造体内のリスト参照の仕方 19593 たいちう 2005/01/27 18:05:17


No.19593

Re:自己参照構造体内のリスト参照の仕方
投稿者---たいちう(2005/01/27 18:05:17)


こんな感じ?

char filename[128];
int i = 1;
sprintf(filename, "sample%d.txt", i);
fopen(filename, "a+");


この投稿にコメントする

削除パスワード

No.19594

Re:自己参照構造体内のリスト参照の仕方
投稿者---Kei(2005/01/27 18:18:36)


>こんな感じ?
>
>char filename[128];
>int i = 1;
>sprintf(filename, "sample%d.txt", i);
>fopen(filename, "a+");

すみません、説明不足でした。
ファイル名は適当なので
No1.aaaaaa(.txt
No2.bbbbbb(.txt
No3.cccccc(.txt
No4.あいうえお(.txt
※実際は拡張子はひょうじさせてません
ファイル名は20バイトまで表示でそれ以降は切り捨てて表示させています。
上のような感じで
Noが入力されたらフルファイル名+拡張子を取得したいのです。



この投稿にコメントする

削除パスワード

No.19596

Re:自己参照構造体内のリスト参照の仕方
投稿者---たいちう(2005/01/27 18:27:09)


それじゃ strncmp で1つずつ試すのが良いかと。

1)一覧取得
2)一覧表示(取得と同時か?)
3)No.入力
4)ファイル名決定
5)ファイルオープン

という手順なら、1)でフルファイル名を配列に取り込んでしまったらどうでしょうか。
画面に表示させて選ばせるんなら、せいぜい何十件でしょ。


この投稿にコメントする

削除パスワード

No.19597

Re:自己参照構造体内のリスト参照の仕方
投稿者---Kei(2005/01/27 18:39:43)


ありがとうございます。
その方法で取り組んで見ます。
また、詰まったら質問に来そうですが、よろしくお願いします。


この投稿にコメントする

削除パスワード

No.19618

Re:自己参照構造体内のリスト参照の仕方
投稿者---Kei(2005/01/28 11:13:15)


>それじゃ strncmp で1つずつ試すのが良いかと。
>
>1)一覧取得
>2)一覧表示(取得と同時か?)
>3)No.入力
>4)ファイル名決定
>5)ファイルオープン

一応こんな感じまで進んだのですが、
3)のNo入力でファイル名決定するような処理がどうしても分かりません。
どのようにすれば出来るのかご教授お願いします。
それ以前にフルファイル名の取得すら間違っているのでしょうか・・・?
※デバッグ用で今は入力部分がフルパス入力になっています。

/* 構造体宣言 */
struct list{
    char filename[MAX_STRING];
    char sort_time[MAX_STRING];
    struct list *next;
};

/* フォルダ指定関数 */
int folder(char *dir)
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hScanPointer = NULL;
    SYSTEMTIME writeTime;

    struct list *head = NULL;               /* リストの先頭データアドレス */

    char filename[MAX_STRING];
    char filepath[MAX_STRING];
    char edittime[MAX_STRING];
    char editpath[MAX_STRING];
    char select[MAX_STRING];
    char list[MAX_STRING];

    int ret;
    int i = 0;
    int flag;

    memset(list, '\0', sizeof(list));
    memset(filename, '\0', sizeof(filename));
    strcpy(filename, dir);
    strcat(filename, "\\*.txt");            /* テキストだけ検索 */
    
    hScanPointer = FindFirstFile(filename, &FindFileData);
    
    if(hScanPointer == INVALID_HANDLE_VALUE){
        return OK;
    }
    flag = 0;
    do{
        memset(edittime, '\0', sizeof(edittime));
        /* ファイル時間取得 */
        FileTimeToSystemTime( &FindFileData.ftLastWriteTime, &writeTime);
        /* 更新時間ソート用に時間を編集 */
        sprintf(edittime, "%d%02d%d%d%d%d", writeTime.wYear, writeTime.wMonth, writeTime.wDay, writeTime.wHour, writeTime.wMinute, writeTime.wSecond);
        /* リスト編集関数呼び出し */
        head = add_list(FindFileData.cFileName, edittime, head, list);
    } while(FindNextFile(hScanPointer, &FindFileData));
    
    /* 編集したリストの表示 */
    show_list(head);

    printf("\n");

    printf("ファイル詳細情報を取得したいのであれば1を\n");
    printf("ファイル編集をしたいのであれば2を選択してください。\n");
    printf("それ以外のキーを入力した場合、メニューに戻ります。\n");

    scanf("%s", &select);
    getchar();
    printf("\n");

    switch(atoi(select)){
        case 1:
            printf("フォルダ内の情報取得したいファイルNoを指定してください。\n");
            memset(editpath, '\0', sizeof(editpath));
            memset(filepath, '\0', sizeof(filepath));
            strcpy(editpath, strtok(filename, "*"));
            scanf("%s", &filepath);
            printf("\n");
            strcat(editpath, filepath);
            file_info(editpath, list);

            break;
        case 2:
            printf("編集をおこなうファイルNoを指定してください。\n");
            memset(editpath, '\0', sizeof(editpath));
            memset(filepath, '\0', sizeof(filepath));
            strcpy(editpath, strtok(filename, "*"));
            scanf("%s", &filepath);
            printf("\n");
            strcat(editpath, filepath);
            file_edit(editpath);
            break;
        default:
            printf("メニューに戻ります。\n");
            ret = menu("0");
            if(ret != OK){
                return NG;
            }
            return OK;
    }

    /* 編集したリストの開放 */
    free_list(head);
    return OK;
}

/* ソート関数 */
struct list *add_list(char *filename, char *edittime, struct list *head, char *list)
{
    struct list *prev;
    struct list *cur;
    struct list *point;

    if ((point = (struct list *) malloc(sizeof(struct list))) == NULL) {
        printf("領域確保失敗\n"); 
        exit(1);
    }

    /* リストにデータ登録 */
    strcpy(point->filename, filename);
    strcpy(point->sort_time, edittime);
    strcpy(list, filename);    /* フルファイル名を格納 */

    /* 初期はデータが無いのでNULLで初期化 */
    point->next = NULL;
    if (head == NULL || strcmp(edittime, head->sort_time) > 0) {
        /* 今までの先頭ポインタを次のポインタに入れる */
        point->next = head;
        return point;
    }
    for (prev = cur = head; (cur = cur->next) != NULL; prev = cur) {
        if (strcmp(edittime, cur->sort_time) > 0) {
            point->next = cur;
            break;
        }
    }

    /* ポインタの繋ぎ変え */
    prev->next = point;
    return head;
}




この投稿にコメントする

削除パスワード

No.19621

Re:自己参照構造体内のリスト参照の仕方
投稿者---たいちう(2005/01/28 11:44:11)


show_listでファイル名を全て順番に表示しているのだと思いますが、
これを応用してリストのN番目のファイルを返す関数は作れますか?


この投稿にコメントする

削除パスワード

No.19623

Re:自己参照構造体内のリスト参照の仕方
投稿者---Kei(2005/01/28 13:06:15)


>show_listでファイル名を全て順番に表示しているのだと思いますが、
>これを応用してリストのN番目のファイルを返す関数は作れますか?

ありがとうございます!
たいちうさんのヒントのおかげで出来ました。
動作が取れた関数を記述しておきますのでまずいところがあったら
指摘をお願いします。
/* 指定したNoのフルファイル名取得関数 */
/* pointは取得したリスト、selectはscanfで取得した値、select_fileが取得したフルファイル名です。 */
int select_list(struct list *point, char *select, char *select_file)
{
    int no_cnt = 0;

    while(point != NULL){
        no_cnt++;
        /* scanfで入力した値とカウンタが一致したらファイル名を返す */
        if(atoi(select) == no_cnt){
            strcpy(select_file, point->filename);
        }else{
            /* Noとカウンタが一致してなければ次ポインタを進める */
            point = point->next;
        }
    }
    return OK;
}

本当にありがとうございました。



この投稿にコメントする

削除パスワード

No.19637

Re:自己参照構造体内のリスト参照の仕方
投稿者---たいちう(2005/01/28 14:05:03)


> 指摘をお願いします。

とのことなので、直さなくても特に大した問題はないと思いますが、

1.
ファイルが見つかったら、そこでreturn OK;しましょう。
探索の無駄を省くこともありますが、見つからなかった場合、
どうするかも考えた方が良いでしょう。
このままでは、リストの長さが10でselectが20の場合、
見つからなかったのにreturn OK;になります。
*select_fileをNULLで初期化しておくことと、
見つからなかったらreturn NG;とでもするが良いかと。

2.
selectはint型で渡した方が私の好みです。
少なくともwhileの中で毎回atoiを呼ぶ必要はないです。

私が作るならこうかな。

// listのselect番目の構造体へのポインタを返す。
// 見つからなければ、NULL
struct list* search_list(struct list *point, int select);


この投稿にコメントする

削除パスワード

No.19638

Re:自己参照構造体内のリスト参照の仕方
投稿者---Kei(2005/01/28 14:34:30)


>1.
>ファイルが見つかったら、そこでreturn OK;しましょう。
>探索の無駄を省くこともありますが、見つからなかった場合、
>どうするかも考えた方が良いでしょう。
>このままでは、リストの長さが10でselectが20の場合、
>見つからなかったのにreturn OK;になります。
>*select_fileをNULLで初期化しておくことと、
>見つからなかったらreturn NG;とでもするが良いかと。

おっしゃる通りテストをしてみたらリストサイズ以上の数字や
文字を打ち込んだらおかしな動作になりました。(汗
数字文字判定はisxdigit()で
リストサイズはカウントでリスト長さ以上の数字だったらreturn NG;
を返すようにしました。(汗

>
>2.
>selectはint型で渡した方が私の好みです。
>少なくともwhileの中で毎回atoiを呼ぶ必要はないです。
>
>私が作るならこうかな。
>
>// listのselect番目の構造体へのポインタを返す。
>// 見つからなければ、NULL
>struct list* search_list(struct list *point, int select);

なるほどー
色々参考になりました。
本当にどうもありがとうございました。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧