• ベストアンサー

ファイル入力したデータの行数の数え方は?

ファイル入力した漢字データ(全角)を読み込み、行数を数えながら逆から表示するプログラムはどうかいたらいいのですか? 実行結果例 (例として、次のようなA:_TEST.DAT を入力する) 「上を向いて、歩こう。涙がこぼ  れないように。泣きながら、歩  く一人ぼっちの夜。」 ファイル名を入力して下さい:A:_TEST.DAT ↓ 1: ぼこが涙。うこ歩、てい向を上 2: 歩、らがなき泣。にうよいなれ 3: 。夜のちっぼ人一く

noname#1519
noname#1519

質問者が選んだベストアンサー

  • ベストアンサー
  • arthur
  • ベストアンサー率34% (15/43)
回答No.3

なんだか課題っぽい感じがするのですが・・・面白そうなので考えてみました。 データの文字は全角文字のみと考えてよろしいでしょうか? ファイルをオープンし、1行ずつ読み込んで配列に格納し、配列の後ろから表示していくという考え方で作ってみました。 しかし全角文字(2バイト文字)なので、そのまま逆から表示しただけでは、まったく違う文字が表示されてしまうので、 1バイト目と2バイト目を入れ替える必要があります。 例)「あ」という文字を配列に格納すると・・・ 配列の0番目:0x82 配列の1番目:0xA0 というふうに格納されます。 しかし、配列の後ろから表示した時に「あ」と表示されるには 配列の0番目:0xA0 配列の1番目:0x82 と格納されていなければならないので、その処理を入れなければなりません。 データがすべて2バイト文字ならば、配列の要素が偶数の時に1バイト目、奇数の時に2バイト目が必ずくるので、 1バイト目ならば、+1した場所に(上の例で言えば、配列の1番目)、 2バイト目ならば、-1した場所に(上の例で言えば、配列の0番目)入替えやればいいわけです。(わかりにくいかな?^^;) その処理を行の終わり(改行文字の手前)まで繰り返して、printf文で配列の後ろから1文字ずつ表示していけば「あいうえお」が「おえういあ」と逆に表示されます。 1行終わったら、また1行読み込んでこの処理をファイルの終わり(EOF)まで繰り返せば、 希望どおりの結果になると思います。 ・・・とまぁ、とりあえず考え方だけをアドバイスしたのでわかりにくい文章かもしれませんが、これをもとに自分の力で完成させてみてくださいね^^ 不明な点があれば補足してください。 本当は専門家のarthurでした(自信ないから経験者・・(爆))

その他の回答 (4)

  • y_oku
  • ベストアンサー率62% (25/40)
回答No.5

もし課題や大きなアプリケーションの一部などではないのならば、 Perlを使ったほうが早いと思います~。 DOSプロンプトから、 perl -e "print map{ ++$i; \"$i: $_\" } reverse <>;" TEST.DAT だけでいいですよ。

  • selenity
  • ベストアンサー率41% (324/772)
回答No.4

あうっ、逆から表示を見落としていました、、、 まず、1-byte文字ずつ読んでShift-JISの日本語の 1バイト目に相当する文字であったらもう1文字 読んで、これが日本語の2バイト目に相当する文字 であればこの2バイトはこのままの順番で、この後に 今までの文字列を追加します。 Shift-JISコードの日本語は1Byte目にくるcharactor、 2Byte目にくるcharactorの範囲が決まっていますので、 このあたりで日本語か半角英数字かどうかを 比較しましょう。 または、日本語2Byteを1文字として文字単位で扱える 関数があるかもしれません。探してみましょう。 日本語Basic系(VBAなど)は結構装備してますよ。

  • haporun
  • ベストアンサー率40% (230/562)
回答No.2

あなたがどこからどの辺までわかっているのか知りたいです。 さすがにこれに全部答えるのには気が知れます。 どこかの学校の問題っぽいです。 TurboCを使っているということはDOS上ですよね。 DOSでは日本語にShift-JISという文字コートが使われており、そのコードの文字列を逆から操作するのは、非常に難しいことです。 日本語コードの部分をひっくり返さないようにしなければならないのですが、Shift-JISではどこが日本語なのかを区別するのが非常に困難です。 >~漢字データ(全角)を読み込み~ もし本当に、全角文字しか読み込まないのなら、forで1バイト走査して改行コードが見つかったら、後ろから2バイトずつ戻って別の配列に書き込んでいけば良いでしょう。

noname#1519
質問者

補足

ファイルのオープンや行数をつけて表示することはわかります。漢字は2バイトということなので逆からの表示のしかたでつまっています

  • selenity
  • ベストアンサー率41% (324/772)
回答No.1

fgetsを使って行単位で読み込んでもいいですし、 fgetcで1文字ずつ読み込み、0x0aが来たら行末と 見なと良いでしょう。

関連するQ&A

  • ファイルの入力、出力

    #include<stdio.h> int main(){ int a,b; FILE *fp0, *fp1;   fp0 = fopen("test1.dat", "r"); if( fp0 == NULL ){ printf("Cannot open test1.dat"); exit(1); } fp1 = fopen("file.txt", "w"); while((fscanf(fp0, "%d %d", &a,&b)) != EOF){ fprintf(fp1, "%d %d\n", a*a,b*b); } fclose(fp0); fclose(fp1); return(0); } test1.datファイルを読み込んで、変数a,bに値をいれ、 その二乗結果をfile.txtに書き込むプログラムなのですが test1.datファイルに書き込まれてる値をどのようにa,bに代入されているのかわかりません。 例えば test1.datが 1 2 3 4 5 であると、 file.txtには 1 4 9 16 25 16 と書き込まれています。 test1.datが 1 1 2 2 3 3 であると file.txtには 1 1 4 4 9 9 となっています。 どのように、変数に値が入るのでしょうか??

  • エクセルVBAでボタンを割り当てて、そこに入力行数とCSV形式出力をおこなうように記述したい。

    エクセルのVBAでエクセルの入力データをCSVに出力するVBAを書こうとしておりますが、2点ほどわかりません。 まず、入力行数を調べたいのですが、A列で入力があるところまでを個数としたいのですがどのように求めるかわかりません。 あと、データをCSV形式でファイルに落としたいのですがどうすればよいのでしょうか? Dim fp As Integer Dim fname As String dim num as integer num = 入力数(たとえば、a列に入力がある行数など)  msgbox("入力行数=" & cstr(num) & "です。") fname = "test.csv" fp = FreeFile Open fname For Output As #fp CSV形式で出力する Close #fp

  • マクロ データが入力されたら同じ行に式を書き込む

    よろしくお願いします。作りたいマクロがあって、毎日少しずつやっています。 自分でも、やりたいことがうまく説明できていないかも知れませんが その際には、補足説明いたしますので、どなたか教えてください A1には行数を指定する数値が入力されています 例 5 A1に入力してある数値をマクロでチェックします 1以上20以下の整数値なら(1)以降の処置をします それ以外の数値なら無視してなにもしません (1)C2からA1で指定した行数の範囲で数値が入力されたら(2)をします 例 A1が5なら 入力範囲はC2からC6になります (2)Dの同じ行に式 =$A$2*(1)で入力された数値 をマクロで書き込む 例C2に数値が入力されたらD2に式をマクロで書き込みます (1)で範囲外にデータが入力されたら何もしません(無視します) 以上です。よろしくお願いします

  • エクセル、行数をカウントしたい。

    エクセル初心者です。 よろしくお願いいたします。 エクセルでこのような表を作っています。   A  B  C 1 10 15 2 20 3    10 4    15 5 10 6 10 10 7 8 この時、データの入っている行数をカウントしたいのです。 上の例では 「6」 です。 途中に空白の行はありません。 A列、B列にはどちらにも数字が入る場合と、どちらかにしか 入らない場合があります。 なので COUNT は使えないですよね? 今まではデータを入力後、下の空白の行を削除し、C列で COUNTBLANK として求めていたのですが、表の長さ(行数)が一定でないため、 体裁が悪くなってしまっていました。 希望としては。 最終行のC列に「終了」などと入れると、その文字列を判別 してくれて、それより上の行数をカウントしてくれる。 または 例えば OR を使って、A列B列どちらかにデータがある 場合のみ、カウントしてくれる。 こんなワガママなことができたら、と思っております。 補足が必要ならばいたします。 それと、遅くなるかもしれませんが、お礼は必ずさせていただきます。

  • 【エクセル】セルに入力された数字の行数だけ印刷するには?

    いつも利用させていただいています。 A1のセルに「3」「5」など数字を入力して 印刷ボタンを押すと 数字の行数分だけ印刷することは可能なのでしょうか? 【イメージ】     A列   B列 1行目 3 2行目 商品A 1万円 3行目 商品B 2万円 4行目 商品C 2.5万円 5行目 商品D 3万円 6行目 商品E 5万円  ※1行目(セルA)で出力したい行数を指定  ※2行目以降は商品情報が記載されている  ※このケースだと「3」とA1に入力されたので、   行数が入力された1行目と商品情報を頭から3行分(印刷範囲A1~B4)まで印刷。   もし「5」と入力されたらA1~B6まで印刷したい。 行を表示・非表示したり、印刷範囲を指定したりすればできるのだと 思いますが・・・このファイルの利用者によって出力が必要な行数が異なり、 年配の方々に印刷範囲の指定をしていただくのが難しくて 困っています・・・。 どなたかご存知の方、よろしくお願いいたします!!

  • 大量の入力ファイルを扱うとき、for文などで簡略化できる?

    例えば、"input_1.dat", "input_2.dat" ... "input_9.dat","input_a.dat" ... "input_z.dat"のように、 ファイル名が一定のフォーマットに従った 入力ファイル群があるとします。 (ファイル内の数値の配置フォーマットも一緒) これらのファイルの中身を fopen→fscanf→fcloseを使って読みこむとき、 FILE *fin1, *fin2; fin1 = fopen("input_1.dat","r"); fin2 = fopen("input_2.dat","r"); ... のようにファイル名をひとつひとつ読みこまず、 for, whileなどを用いて簡単に書けないでしょうか?

  • ファイルを読み込んで入力する方法

    C++についての質問です。 あるファイル(テキストでもエクセルでもCSVでも可)に書かれている数値を読み込んで、プログラム内で入力する方法が知りたいです。 例えば、"test.txt"というファイルに 1 2 3 4 5 3 2 3 1 2 というような数字の羅列があった場合に、プログラムのmain関数内の {x1[0],x2[0],x3[0],x4[0],x5[0]} {x1[1],x2[1],x3[1],x4[1],x5[1]} のような場所に、順番に入れて行きたいです。 "a.txt"の中の1行目を左から順にx1[0],x2[0],x3[0],x4[0],x5[0]に入力し、次に2行目を同じく左から順に・・・というように、"a.txt"ないの行数だけ入力していけるプログラムを考えています。 どなたかご教授していただけないでしょうか。 拙い文章で申し訳ありません。

  • ファイル入力

    1 20 2 30 3 95 4 52 5 90 3 Maximum  上記の様な入力ファイルinput.datのうち1~5行目のデータを表示するプログラムを作っています。  6行目は空白で、7行目は2列目の中で最大値をとる行の1列目の数値が入っています。  1列目の数値は最後の行を除いて重複することはありません。  入力データの行数はファイルによって最大20行まで変動します。列数は2列で固定です。  以下のプログラムのままでは6行目以降のデータも読み取ってしまい、出力がおかしくなってしまいます。  1~5行目のデータのみ出力するにはどうしたらよいでしょうか。  ご存知の方、お手数ですが教えてください。よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #define row 20 #define col 2 int main(){ int i,j,data[20][2]; FILE *fp; if((fp=fopen("input.dat","r"))==NULL){ fprintf(stderr,"Cannot open file input.dat\n"); exit(1); } for(i=0;i<row;i++){ for(j=0;j<col;j++){ fscanf(fp,"%d",&data[i][j]); printf("%d ",data[i][j]); } printf("\n"); } fclose(fp); return 0; }

  • DATファイルが読めません(VB・VBA)

    DATの読書きをしなくちゃいけない事になって 元のコードを元に書き出す事はできたのですが 読込みができなくて困っています。構造体の中に値を入れてるんですが msgboxで値を表示しても、空白しか返ってきません。 ネットでも検索してみたんですが、どこがおかしいの分からなくてお手上げです。 どなたか宜しければおかしい所を教えて下さい。 Type TEST_DAT  TEST_A as string * 1  TEST_B as string * 2  TEST_C as string * 3 End Type Sub a ()  Dim Dat as TEST_DAT  Dim Fn as integer  Fn = FreeFile  Open ThisWorkbook.path & "\Test.dat" For Random as #Fn Len = 6  Get #Fn , , Dat  Msgbox Dat.TEST_A  Msgbox Dat.TEST_B  Msgbox Dat.TEST_C  Close #Fn  End Sub Datファイルの方には、上の構造体を使ってPut #Fn,,Dat の様に書いて1行出力した物をそのまま使っています。 なので、データが無いって事はありません。 元のコードとネットで調べはしたのですが、上で問題無い様な気がして おかしい場所がさっぱりわかりません。エラー等は一切返ってきてません。 Msgbox Len(Dat.TEST_A)の様にすると1,2,3と帰って来るので 値が入ってないのが悪いとはわかるんですが…。

  • 履歴ファイルの削除方法?

    履歴ファイルを filename_YYYYMMDDhhmmss.dat という名前で作成しています。 今日から日付で4世代以前のファイルを削除したい場合(最新3世代を残す)、 どのようにすればよいのでしょうか? 削除は、シェルスクリプト(b shell)で行います。 perl,awkは使わないでお願いします。 例 test_new.dat ←残る (削除対象外) test_old.dat ←残る (削除対象外) test_old.dat_20060610000000 ←消える test_old.dat_20060610000001 ←消える test_old.dat_20060611000000 ←消える test_old.dat_20060611000001 ←消える test_old.dat_20060612000000 ←消える test_old.dat_20060612000001 ←消える test_old.dat_20060613000000 ←残る (3世代目) test_old.dat_20060613000001 ←残る (3世代目) test_old.dat_20060614000000 ←残る (2世代目) test_old.dat_20060614000001 ←残る (2世代目) test_old.dat_20060615000000 ←残る (1世代目) test_old.dat_20060615000001 ←残る (1世代目)