掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

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

No.25703

dump処理について
投稿者---セイジ(2006/01/25 11:51:56)


初めて投稿します。現在c言語勉強3週間の超初心者なのですが・・・。

・最後の無駄な表示
・バック時行数表示
・最初のページ表示時 バックナビを消す バックできなくする
・最後のページ表示時 次ページナビを消す 次ページにいけなくする

上記の内容で解決できず悩んでおります。
初歩的な問題で申し訳ありませんがご教授頂けます様
宜しくお願い致します。
OS:win2000 コンパイラ:borland c++builder

#include<stdio.h>
#include<conio.h>
#include<process.h>
#define RETU 16
#define MOJIRETU 16
#define GYOU 22
#define KENSAKU_CHI 100000
#define ASCII_CODE_TAB 9
#define ASCII_CODE_PARAGRAPH 10
#define ASCII_CODE_RETURN 13
#define ASCII_CODE_SPACE 32

int JYUROKU(void);
int MOJI(void);
void PAGE(void);

FILE *fp;
FILE *fp1;

char c,d,e,y;

int i,j,t,z;

int main(){ 

    char g;
        
    /*オープンしたファイルをバイナリモードでポインタに代入*/
    fp  = fopen("youbikaizen.c","rb");
    fp1 = fopen("youbikaizen.c","rb");
    
    /*NULL == プログラム終了*/
    if( fp == NULL || fp1 == NULL){
        printf("ファイルのオープンに失敗しました。\n");
        exit(-1);
    }

    for(;;){
        
        /*頁頭に表示される、列番号*/
        printf("       +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F "
        "0123456789ABCDEF\n");

        /*16進&文字の出力関数*/
        JYUROKU();

        printf("\n");
        
        printf("<w>改ページ <b>ページBack <e>終了\n");
        
        /*頁の進み戻り&終了*/
        PAGE();
        
        g = ( g = c );
            
        /*'e' == 無限ループ脱出*/
        if( g == 'e' ){
            break;
        }
        

    }
    
    fclose(fp);
    
    return 0;
    
}

/*16進と文字と一列を一文づつ表示*/
int JYUROKU(){
    
    for( j = 0 ; j < GYOU ; j++ ){
        
        t = t+1;
        printf("%05X0 ", 0x0000FF & c );
        
        /*16進出力を16回(16列)までループ*/
        for( i = 0 ; i < RETU ; i++ ){
            
            /*データを一つ取って(c)に代入*/
            c = fgetc(fp);
            
            if( c == EOF ){
                return 0;
            }
            /*(c)に代入された値を16進に変換して出力*/
            printf("%02X ", 0x0000FF & c );
            
        }
        /*16列の文字の出力*/
        MOJI();
        
        printf("\n");
    }
    
    return t;
    
}

/*文字を一文づつ16列になるまで表示して行く関数*/
int MOJI(){
    
    /*文字出力を16回(16列)までループ*/
    for( i = 0 ; i < MOJIRETU ; i++ ){
        d = fgetc(fp1);
        
        if( d == EOF ){
            return 0;
        }
            
            /*該当する文字に対してすべてピリオドに変換*/
            if( d == ASCII_CODE_TAB || d == ASCII_CODE_PARAGRAPH
                || d == ASCII_CODE_RETURN || d == ASCII_CODE_SPACE ){
                d = '.';
                printf("%c", d);
            }
            /*該当しない文字に関しては文字出力*/
            else{
                printf("%c", d);
            }
    
    }
    
    return 0;
    
}

/*頁の切り替え*/
void PAGE(){
    
    for(;;){
            
            switch( c = getch()){
                
                /*頁Back*/
                case 'b':
                    fseek( fp ,-704L,SEEK_CUR );
                    fseek( fp1,-704L,SEEK_CUR );
                    break;
                    
                /*プログラム終了*/
                case 'e':
                    printf("本当に終了しても宜しいでしょうか? yes<y> or no<n>");
                    fclose(fp);
                    fclose(fp1);
                    z = KENSAKU_CHI;
                    break;
                    
                /*改頁*/
                case 'w':
                    fseek(fp,-0L,SEEK_CUR);
                    fseek(fp1,-0L,SEEK_CUR);
                    break;
                
                /*その他の入力*/
                default:
                    printf("入力されたキーは無効です。\n");
                    printf("もう一度入力し直して下さい。\n");
                    break;
                    
            }
        
        /*該当 == 無限ループ脱出*/
        if( c == 'b' || c == 'w' || c == 'e' ){
            break;
        }
        
    }
    
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:dump処理について 25710 RAPT 2006/01/25 13:48:25


No.25710

Re:dump処理について
投稿者---RAPT(2006/01/25 13:48:25)


> ・最後の無駄な表示
> ・バック時行数表示
> ・最初のページ表示時 バックナビを消す バックできなくする
> ・最後のページ表示時 次ページナビを消す 次ページにいけなくする
> 
> 上記の内容で解決できず悩んでおります。

で?
そのコードを実行させて、問題点を確認し、解決しろと?

これでは、【掲示板利用宣言】の
・課題の丸投げはしません。
・環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
に抵触します。


> ・最後の無駄な表示
何が"無駄"なのですか?

> ・バック時行数表示
何を行数として表示したい?

> ・最初のページ表示時 バックナビを消す バックできなくする
ファイルポインタがどこを指しているかを、ftell() 関数で取得できます。
あとは、最初にファイルを読み出すときの ftell() の返す値を保存して
おいて、それと現在の ftell() の値とを比較すればできるのでは?

> ・最後のページ表示時 次ページナビを消す 次ページにいけなくする
読み出した値が EOF のときで、エラーでなければ、それがファイル終端です。

ヒントとか、思ったこと。
・グローバル変数はなるべく使わないほうが良いです。
・最後、fclose(fp1); が抜けています。
・変数 z の目的は?
・printf("本当に終了しても宜しいでしょうか? yes<y> or no<n>");
 の目的は?

# 本題とは関係ないけど、
# > #define ASCII_CODE_PARAGRAPH 10
# '\r'(0x0d) は CR(Carriage Return: 復帰文字)なのでOKですが、
# '\n'(0x0a) は LF(Line Feed: 改行文字)なのですが・・・



この投稿にコメントする

削除パスワード

No.25711

Re:dump処理について
投稿者---RAPT(2006/01/25 14:02:05)


>  ・最後、fclose(fp1); が抜けています。
ああ、PAGE() 関数で
> fclose(fp);
> fclose(fp1);
とかしてるのか。
なら、main() 関数の方は除去しないと。

でもmain()でfopen()してるので、fclose()もmain()内で処理した方が
自然だと覆います。




この投稿にコメントする

削除パスワード

No.25712

Re:dump処理について
投稿者---RAPT(2006/01/25 14:15:47)


あ、グローバル変数の弊害発見。
左側の6桁の16進表示が正しくない。
最後に読み込んだ文字のバイト*0x10が表示されているだけ。



この投稿にコメントする

削除パスワード

No.25713

Re:dump処理について
投稿者---RAPT(2006/01/25 15:31:32)


// いつものコメントなしバージョン。(WindowsXPsp2/VC++6sp6/Console-C)

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

typedef unsigned char BYTE;
//static const int ASCII_TAB = '\t', ASCII_CR = '\r', ASCII_LF = '\n', ASCII_SP = ' ';
static const int END_PROGRAM = 10000;
enum{ RETU = 16, GYOU = 22, PAGESIZE = RETU * GYOU, };

int putLine(FILE* fp)
{
    int i, j;
    char c = 0, text[1 + RETU] = {0};
    for( j = 0 ; j < GYOU && c != EOF ; j++ ){
        printf("%05X0 ", ftell(fp) / 16 );
        for( i = 0 ; i < RETU ; i++ ){
            c = fgetc(fp);
            if( c == EOF ){
                printf("%*s", 3 * (RETU - i), "");
                text[i] = '\0';
                break;
            }
            printf("%02X ", (BYTE)c );

            if( isgraph(c) ){
                text[i] = c;
            }else{
                text[i] = '.';
            }
        }
        printf("%s\n", text);
    }
    return c;
}

int selectMenu(FILE* fp, int top, int result)
{
    static long last = 0;
    int c;
    long cur = ftell(fp);
    if( !feof(fp) ){
        last = cur;
    }

    putchar('\n');
    if( result != EOF ){
        printf("<w>改ページ ");
    }
    if( !top ){
        printf("<b>ページBack ");
    }
    printf("<e>終了\n");

    for(;;){
        c = getch();
        if( c == 'e' ){
            // end
            return END_PROGRAM;
        }
        if( c == 'w' && result != EOF ){
            // next
            break;
        }
        if( c == 'b' && !top ){
            // back
            if( cur <= PAGESIZE ){
                fseek(fp, 0, SEEK_SET);
            }else if( feof(fp) ){
                fseek(fp, last - PAGESIZE, SEEK_SET);
            }else{
                fseek(fp, -2 * PAGESIZE, SEEK_CUR);
            }
            break;
        }
        printf("入力されたキーは無効です。\n");
        printf("もう一度入力し直して下さい。\n");
    }
    return 0;
}

int main(void)
{
    long lastPtr = 0, curPtr = 0;
    int result = 0, top;
    FILE* fp = NULL;

    fp = fopen("ctest.c", "rb");
    if( fp == NULL ){
        fprintf(stderr, "ファイルのオープンに失敗しました。\n");
        exit(-1);
    }

    do{
        system("cls");
        puts("       +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF");
        top = ( ftell(fp) / 16 == 0 );
        result = putLine(fp);
    }while( END_PROGRAM != selectMenu(fp, top, result) );

    fclose(fp);
    return 0;
}

// 色付けすると文字数オーバー気味・・・



この投稿にコメントする

削除パスワード

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