掲示板利用宣言

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

 私は

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

掲示板2

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

No.26142

ファイル読み込みと関数の引数
投稿者---がりんしゃ(2006/02/15 20:23:48)


下のソースのように、読み込んだファイルを関数で表示する場合、関数の引数はどのようにすれば良いのでしょうか?

//ソース


int main()
{
    char  fnamein[100];
    FILE  *fin;

    //オープンするファイル指定

    printf("入力ファイル名:");
    scanf("%s",fnamein);

    //ファイルオープンエラー

    if((fin = fopen(fnamein,"r")) == NULL)
    {
        printf("%sを開けません\n",fnamein);
        exit(0);
    }

    //ここ以降を関数にしたい

    char cdata[256];
    int idata = 0;
    int Line_cnt = 0;

    //1行ずつ全て表示

    while(fgets(cdata,256,fin) != NULL)
    {
        Line_cnt++;
        idata = atoi(cdata);
        printf("%d ",Line_cnt); //行数表示

        printf("%x ",idata);  //16進表記

        printf("%s",cdata);  //ファイル内データ表示

    }
    return 0;
}

このソースだと、読み込んだファイルをmain関数内で行数分全て表示してしまっているのですが、

・指定した1行だけ表示させる関数line_display()で、指定した1行だけ表示させる
・関数all_display()で、line_display()を必要分読んで、指定した行から25行表示させる

というように関数で表示させたいのですが、line_display(),all_display()を呼ぶときの引数をどのように設定すればよいのかわかりません。

アドバイス宜しくお願い致します。

環境はWindowsXP、Microsoft Visual C++6.0で、C++として作っています。






この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ファイル読み込みと関数の引数 26143 KING・王 2006/02/15 20:41:11
<子記事> Re:ファイル読み込みと関数の引数 26149 中2 2006/02/16 00:11:38


No.26143

Re:ファイル読み込みと関数の引数
投稿者---KING・王(2006/02/15 20:41:11)


line_display()、all_display()の両方とも、ファイルポインタfinと、
表示したい行番号をひきすうとすればOKでは?



この投稿にコメントする

削除パスワード

No.26144

Re:ファイル読み込みと関数の引数
投稿者---REE(2006/02/15 21:06:05)


>line_display()、all_display()の両方とも、ファイルポインタfinと、
>表示したい行番号をひきすうとすればOKでは?

一見そう見えて実は駄目だったりして・・
なぜなら、今どこまで読んでいるか分からないから。

line_display(fin, 5); //1-4行目読み飛ばす?
line_display(fin, 8); //6,7行目読み飛ばす?
line_display(fin, 5); //戻る??



この投稿にコメントする

削除パスワード

No.26145

Re:ファイル読み込みと関数の引数
投稿者---がりんしゃ(2006/02/15 21:25:38)


実現したいのは、
1.ファイル読み込み
2.ファイル1画面分(24行)表示
3.キー入力を待ち、あるキー(例えば'A')と入力したときに、行数を指定して、その行を表示

としたいのですが・・・。わからないのは、ファイルポインタfinに入ってるファイルのデータをどのように関数に持ってくか、です。
main関数内で全て読み込んで配列に格納してから関数に持って行く・・・というのも考えましたが・・。


また、別の質問なんですが、プログラム内で文字を16進に変換しなければならないのですが、
文字(char)を16進で表記する方法というのはどのようにするのでしょうか?
12345678を16進にすると3132 3334 3536 3738になるようですが、わかりません・・・。

宜しくお願いします。



この投稿にコメントする

削除パスワード

No.26147

Re:ファイル読み込みと関数の引数
投稿者---がりんしゃ(2006/02/15 21:33:52)


>12345678を16進にすると3132 3334 3536 3738になるようですが、わかりません・・・。

少し調べただけで、こうなる理由はわかりました。すいません。

ただ、これをプログラムで実現するとなると・・・。この文字コードに規則性を持たせて変換することなどできるでしょうか?

関数の引数の問題と合わせて宜しくお願いします。



この投稿にコメントする

削除パスワード

No.26155

Re:ファイル読み込みと関数の引数
投稿者---とろり(2006/02/16 11:06:12)


こんにちは。

> この文字コードに規則性を持たせて変換することなどできるでしょうか?

ASCII文字コードだと '0' は16進で 0x30
たしか 0-9 までの文字の並びは保障されていたから

'1' == '0' + 1 == 0x31

かな。


この投稿にコメントする

削除パスワード

No.26161

Re:ファイル読み込みと関数の引数
投稿者---とろり(2006/02/16 12:09:16)


ちなみに文字をそのままコードで16進出力だけなら、そのように書式指定してやれば良いよ。

printf("%02x%02x\n", '1', '2');



この投稿にコメントする

削除パスワード

No.26148

Re:ファイル読み込みと関数の引数
投稿者---KING・王(2006/02/15 22:18:16)


>line_display(fin, 5); //1-4行目読み飛ばす?
>line_display(fin, 8); //6,7行目読み飛ばす?
>line_display(fin, 5); //戻る??

あっ、もちろんline_display()関数の先頭で、
毎回fseek()でファイル先頭までファイルポインタを移動させるということで。



この投稿にコメントする

削除パスワード

No.26149

Re:ファイル読み込みと関数の引数
投稿者---中2(2006/02/16 00:11:38)


>・指定した1行だけ表示させる関数line_display()で、指定した1行だけ表示させる
>・関数all_display()で、line_display()を必要分読んで、指定した行から25行表示させる


line_display()までですが・・
もっと効率のいい方法があるような気がします
それから「16進表示」の意味がわからないので投稿されたソースのまま挿入しました


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

char *line_display(FILE *fin,int line_cnt)
{
    static char str[256];
    int i;
    fseek(fin,0,SEEK_SET);//ファイル先頭に移動
    for(i=0;i<=line_cnt;i++)//line_cntで指定された行数まで読む
    {
        if(fgets(str,256,fin) == NULL)//指定した行数が最大行を超えたら
            return NULL;//NULLを返して終了

    }
    return str;//指定された行の文字列の先頭アドレスを返す
}


int main()
{
    char *cdata;
    char  fnamein[100];
    int Line_cnt,idata;
    FILE  *fin;

    //オープンするファイル指定
    printf("入力ファイル名:");
    scanf("%s",fnamein);
    //ファイルオープンエラー
    if((fin = fopen(fnamein,"r")) == NULL)
    {
        printf("%sを開けません\n",fnamein);
        exit(0);
    }
    while(1)
    {
        printf("何行目?:");
        scanf("%d",&Line_cnt);
        if((cdata=line_display(fin,Line_cnt))==NULL)
            break;//存在する行数以上を指定したら終了
        idata = atoi(cdata);//(?)

        printf("%d ",Line_cnt); //行数表示

        printf("%x ",idata);  //16進表記(?)

        printf("%s\n",cdata);  //ファイル内データ表示
    }
    return 0;
}




この投稿にコメントする

削除パスワード

No.26169

Re:ファイル読み込みと関数の引数
投稿者---がりんしゃ(2006/02/16 16:07:12)


とろりさん
>ちなみに文字をそのままコードで16進出力だけなら、そのように書式指定>してやれば良いよ。

>printf("%02x%02x\n", '1', '2');

これだけで出来たんですね。確認しました。ありがとうございます。

>中2さん
fseek(fin,0,SEEK_SET);//ファイル先頭に移動

    for(i=0;i<=line_cnt;i++)//line_cntで指定された行数まで読む

    {
        if(fgets(str,256,fin) == NULL)//指定した行数が最大行を超えたら

            return NULL;//NULLを返して終了


    }

ここをかなり参考にさせていただきました。
関数の引数にはファイルポインタ渡すだけでいいんですね。
ありがとうございました。

かなり長くなりますが、完成したソース載せます。






この投稿にコメントする

削除パスワード

No.26171

Re:ファイル読み込みと関数の引数
投稿者---がりんしゃ(2006/02/16 16:19:41)


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

//プロトタイプ宣言

int KeyInput(FILE *fin, int now_line2, int all_lineA);
int all_display(FILE *fin, int line_assignB);
int line_display(FILE *fin, int line_assignC, int line_cnt);
//----------------------------------------------------

//main


int main()
{
 char fnamein[100];
 FILE *fin;

 //オープンファイル指定

 printf("入力ファイル名:");
 scanf("%s",fnamein);

 //ファイルオープンエラー

 if((fin = fopen(fnamein,"r")) == NULL)
 {
  printf("%sファイルを開けません\n",fnamein);
  exit(0);
 }

 char line_cnt_cdata[256];
 int all_line = 0;
 
 while((fgets(line_cnt_cdata,256,fin)) != NULL)
 {
  all_line++;
 }
 
 int first_display = 0;
 first_display = all_display(fin,1); //起動後、1行目から表示


 int line_assign = 0;

 while(1)
 {
  int line_assign2 = 0;
  line_assign2 = line_assign;

  line_assign = KeyInput(fin,line_assign2,all_line);
 }

 fclose(fin);

 return 0;

}

int line_display(FILE *fin, int line_assignC, int line_cnt) //1行表示関数

{
 char cdataA[256];
 int cntA = 0;
 fseek(fin,0,SEEK_SET);
 for(cntA=0;cntA<=line_assignC-1;cntA++)
 {
  if(fgets(cdataA,256,fin) == NULL)
  {
   return NULL;
  }
 }

 char chr;
 int chr_cnt = 0;
 int chr_spA = 0;
 int chr_spB = 0;

 chr_spB = 1;

 printf("%d    ",line_cnt);  //行数表示

 while((chr = cdataA[chr_cnt]) != '\n') //1行を1文字ずつ改行まで

 {
  printf("%x",chr); //1文字を16進

  chr_spA++;
  if(chr_spA == chr_spB*2) //2文字分表示したらブランク2つ

  {
   printf("  ");
   chr_spB++;
  }
  chr_cnt++;
 }
 
 printf("    ");  //16進表記後、ブランク4つ

 printf("%s",cdataA); //元データ表示


 return 0;
}

int all_display(FILE *fin, int line_assignB) //1画面表示関数

{
 int cntB = 0;
 int line_assignB2 = 0;
 line_assignB2 = line_assignB;

 for(cntB=line_assignB;cntB<(line_assignB2+24);cntB++) //指定した行から24行分1行表示関数を繰り返す

 {
  line_display(fin,line_assignB,cntB);
  line_assignB++;
 }
 return line_assignB2;
}

int KeyInput(FILE *fin, int now_line2, int all_lineA) //キー入力関数

{
 int key = 0;
 int flagA = 0;

 printf(">");
 while(1)
 {
  key = getchar();
  if(key == 'L' || key == 'l') //行数指定表示

  {
   flagA = 1;
   break;
  }
  else if(key == 'E' || key == 'e') //終了

  {
   flagA = 2;
   break;
  }
  else if(key == 'F' || key == 'f') //1行上へスクロール

  {
   flagA = 3;
   break;
  }
  else if(key == 'B' || key == 'b') //1行下へスクロール

  {
   flagA = 4;
   break;
  }
  else if(key == 'U' || key == 'u') //1画面上へスクロール

  {
   flagA = 5;
   break;
  }
  else if(key == 'D' || key == 'd') //1画面下へスクロール

  {
   flagA = 6;
   break;
  }
 //エラー処理できず

  //else

  //{

  // printf("そのキーは受け付けません\n"); //上記以外のキーでエラー処理

  // exit(0);

  //}

 }

 int line_assignA = 0;
 int now_line = 0;

 switch(flagA)
 {
 case 1:
  printf("何行目から表示?\n");
  printf(">");
  scanf("%d",&line_assignA);
  if((all_lineA - line_assignA) < 23)
  {
   printf("1画面表示できません\n");
   exit(0);
  }
  now_line = all_display(fin,line_assignA);
  break;
 case 2:
  exit(0);
  break;
 case 3:
  if(now_line2 <= 1)
  {
   printf("1行上にスクロールできません\n");
   exit(0);
  }
  now_line = all_display(fin,now_line2-1);
  break;
 case 4:
  if(now_line2 == 0)
  {
   now_line2++;
  }
  if((all_lineA - now_line2) < 24)
  {
   printf("1行下にスクロールできません\n");
   exit(0);
  }
  now_line = all_display(fin,now_line2+1);
  break;
 case 5:
  if(now_line2 <= 24)
  {
   printf("1画面上にスクロールできません\n");
   exit(0);
  }
  now_line = all_display(fin,now_line2-24);
  break;
 case 6:
  if(now_line2 == 0)
  {
   now_line2++;
  }
  if((all_lineA - now_line2) < 47)
  {
   printf("1画面下にスクロールできません\n");
   exit(0);
  }
  now_line = all_display(fin,now_line2+24);
  break;
 }
 return now_line;
}

//-----------------------------------------

//入力データ例


12345678
aa112233
1234abcd
   :
   :
25行以上のデータ
//-----------------------------------------


まだエラー処理の部分が上手く出来ませんが質問させていただいたファイルの引数のところと、文字を16進に変換については解決しました。

かなり無駄の多い気もしますが・・・


 





この投稿にコメントする

削除パスワード

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