ファイル入力した漢字データ(全角)を読み込み、行数を数えながら逆から表示するプログラムはどうかいたらいいのですか?

実行結果例
(例として、次のようなA:_TEST.DAT を入力する)
「上を向いて、歩こう。涙がこぼ
 れないように。泣きながら、歩
 く一人ぼっちの夜。」

ファイル名を入力して下さい:A:_TEST.DAT ↓
1: ぼこが涙。うこ歩、てい向を上
2: 歩、らがなき泣。にうよいなれ
3: 。夜のちっぼ人一く

このQ&Aに関連する最新のQ&A

A 回答 (5件)

なんだか課題っぽい感じがするのですが・・・面白そうなので考えてみました。


データの文字は全角文字のみと考えてよろしいでしょうか?

ファイルをオープンし、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でした(自信ないから経験者・・(爆))
    • good
    • 0

もし課題や大きなアプリケーションの一部などではないのならば、


Perlを使ったほうが早いと思います~。
DOSプロンプトから、

perl -e "print map{ ++$i; \"$i: $_\" } reverse <>;" TEST.DAT

だけでいいですよ。
    • good
    • 0

あうっ、逆から表示を見落としていました、、、



まず、1-byte文字ずつ読んでShift-JISの日本語の
1バイト目に相当する文字であったらもう1文字
読んで、これが日本語の2バイト目に相当する文字
であればこの2バイトはこのままの順番で、この後に
今までの文字列を追加します。

Shift-JISコードの日本語は1Byte目にくるcharactor、
2Byte目にくるcharactorの範囲が決まっていますので、
このあたりで日本語か半角英数字かどうかを
比較しましょう。

または、日本語2Byteを1文字として文字単位で扱える
関数があるかもしれません。探してみましょう。
日本語Basic系(VBAなど)は結構装備してますよ。
    • good
    • 0

あなたがどこからどの辺までわかっているのか知りたいです。


さすがにこれに全部答えるのには気が知れます。
どこかの学校の問題っぽいです。

TurboCを使っているということはDOS上ですよね。
DOSでは日本語にShift-JISという文字コートが使われており、そのコードの文字列を逆から操作するのは、非常に難しいことです。
日本語コードの部分をひっくり返さないようにしなければならないのですが、Shift-JISではどこが日本語なのかを区別するのが非常に困難です。

>~漢字データ(全角)を読み込み~
もし本当に、全角文字しか読み込まないのなら、forで1バイト走査して改行コードが見つかったら、後ろから2バイトずつ戻って別の配列に書き込んでいけば良いでしょう。

この回答への補足

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

補足日時:2001/01/25 14:28
    • good
    • 0

fgetsを使って行単位で読み込んでもいいですし、


fgetcで1文字ずつ読み込み、0x0aが来たら行末と
見なと良いでしょう。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qpthread_cond_waitとptherad_cond_signal

pthread_cond_waitで寝ているthreadに対して、ptherad_cond_signalにて起こして、そのthreadが再度寝るまでの間にpthread_cond_signalが複数回(2回として)Callされた場合、どのような挙動になるのでしょうか?

最初のSignalをA、以下B,Cとすると
A->cond_wait->B->cond_wait->C
となるのでしょうか?

宜しくお願い致します。

Aベストアンサー

>waitしていたthreadが稼動している状態でのsignal発行は空振りに終わるということでしょうか?
その通りです。
ptherad_cond_signalが発行されたとき、pthread_cond_waitで待機しているスレッドがなければ、そのシグナルは無視されます。
参考までに下記の実験結果を参照下さい。(空白は全角にしてます)
ソースプログラム
-------------------------------------------
#include  <stdio.h>
#include  <stdlib.h>
#include  <pthread.h>
#include  <time.h>
pthread_mutex_t mut_sub_print = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mut_sub_th = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_sub_th = PTHREAD_COND_INITIALIZER;
int main_sleep_time;
int sub_sleep_time;

void  sub_print(char *name,char *msg,int ctr)
{
  pthread_mutex_lock(&mut_sub_print);
  printf("%s:%s(%d)\n",name,msg,ctr);
  fflush(stdout);
  pthread_mutex_unlock(&mut_sub_print);
}
void  *sub_thread(void *adddr)
{
  int   ctr = 0;
  pthread_mutex_lock(&mut_sub_th);
  while(1){
    pthread_cond_wait(&cond_sub_th,&mut_sub_th);
    ctr++;
    sub_print("sub","con_wait終了",ctr);
    usleep(sub_sleep_time*1000);
  }
  return NULL;
}
// 第1パラメータにメインスレッドのスリープ時間(ミリ秒)
// 第2パラメータにサブスレッドのスリープ時間(ミリ秒)
int main(int argc,char **argv)
{
  int ret;
  int i;
  int ctr = 0;
  pthread_t  tid;
  if (argc != 3){
    printf("%s P1 P2\n",argv[0]);
    printf("P1:メインスレッドのスリープ時間(ミリ秒)\n");
    printf("P2:サブスレッドのスリープ時間(ミリ秒)\n");
    exit(1);
  }
  main_sleep_time = atoi(argv[1]);
  sub_sleep_time = atoi(argv[2]);
  printf("メインスリープ時間=%dミリ秒\n",main_sleep_time);
  printf("サブスリープ時間=%dミリ秒\n",sub_sleep_time);
  ret = pthread_create(&tid,NULL,sub_thread,NULL);
  if (ret != 0){
    printf("pthread_create error:%d\n",ret);
    exit(1);
  }
  usleep(1000);  //1ミリ停止
  for (i = 0; i < 10; i++){
    ctr++;
    pthread_cond_signal(&cond_sub_th);
    sub_print("main","cond_signal完了",ctr);
    usleep(main_sleep_time*1000);
  }
  sleep(10);
  sub_print("main","スレッド停止",0);
  exit(0);
}
---------------------------------------------
第一引数にメインスレッドのスリープ時間
第二引数にサブスレッドのスリープ時間を指定します。
メインスレッド側で、スリープ時間を大きくとり、ゆっくりと
cond_signalを発行すると、空振りが起こりにくくなります。
逆にメインスレッド側で、スリープ時間を小さく取り、
cond_signalを速射すると、空振りが起こりやすくなります。
以下、実行結果。
メインスレッド:300ミリのスリープ
サブスレッド:100ミリのスリープの場合
cond_signal 300 100
メインスリープ時間=300ミリ秒
サブスリープ時間=100ミリ秒
main:cond_signal完了(1)
sub:con_wait終了(1)
main:cond_signal完了(2)
sub:con_wait終了(2)
main:cond_signal完了(3)
sub:con_wait終了(3)
main:cond_signal完了(4)
sub:con_wait終了(4)
main:cond_signal完了(5)
sub:con_wait終了(5)
main:cond_signal完了(6)
sub:con_wait終了(6)
main:cond_signal完了(7)
sub:con_wait終了(7)
main:cond_signal完了(8)
sub:con_wait終了(8)
main:cond_signal完了(9)
sub:con_wait終了(9)
main:cond_signal完了(10)
sub:con_wait終了(10)
main:スレッド停止(0)

メインスレッド:100ミリのスリープ
サブスレッド:300ミリのスリープの場合
cond_signal 100 300
メインスリープ時間=100ミリ秒
サブスリープ時間=300ミリ秒
main:cond_signal完了(1)
sub:con_wait終了(1)
main:cond_signal完了(2)
main:cond_signal完了(3)
main:cond_signal完了(4)
sub:con_wait終了(2)
main:cond_signal完了(5)
main:cond_signal完了(6)
main:cond_signal完了(7)
sub:con_wait終了(3)
main:cond_signal完了(8)
main:cond_signal完了(9)
main:cond_signal完了(10)
sub:con_wait終了(4)
main:スレッド停止(0)

>waitしていたthreadが稼動している状態でのsignal発行は空振りに終わるということでしょうか?
その通りです。
ptherad_cond_signalが発行されたとき、pthread_cond_waitで待機しているスレッドがなければ、そのシグナルは無視されます。
参考までに下記の実験結果を参照下さい。(空白は全角にしてます)
ソースプログラム
-------------------------------------------
#include  <stdio.h>
#include  <stdlib.h>
#include  <pthread.h>
#include  <time.h>
pthread_mutex_t mut_sub_print =...続きを読む

Q_CRT_SECURE_NO_DEPRECATE が効かない?

お世話になっております。
現在、Windows XP、VC++2005 にてプログラム中なのですが、
「strcpy()」についてです。

本ライブラリはセキュリティ強化のため「strcpy_s()」の使用を
奨励されていますが、箇所が多いので取り合えずWarningだけでも
取りたいと思っています。

--
#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
charszBuf[10];
strcpy( szBuf, "test" );

return 0;
}
--

というサンプルコードに対して

warning C4996: 'strcpy' が古い形式として宣言されました。
'strcpy' の宣言を確認してください。
'This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

と出たので、ファイルの先頭に

#define_CRT_SECURE_NO_DEPRECATE

と加えたのですがWarningが取れません。
同様に

#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

としても駄目でした。

他に何か必要なことはあるのでしょうか?
#pragmaは出来るだけ避けたいのですが。

以上、よろしくお願い致します。

お世話になっております。
現在、Windows XP、VC++2005 にてプログラム中なのですが、
「strcpy()」についてです。

本ライブラリはセキュリティ強化のため「strcpy_s()」の使用を
奨励されていますが、箇所が多いので取り合えずWarningだけでも
取りたいと思っています。

--
#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
charszBuf[10];
strcpy( szBuf, "test" );

return 0;
}
--

というサンプルコードに対して

warnin...続きを読む

Aベストアンサー

stdafx.hがあるならstdafx.hに
#define _CRT_SECURE_NO_DEPRECATE
を記述されたら良いと思います

QAES暗号にて、AES_set_encrypt_keyで設定されるAES_KEYについて

VC++2008にてopensslを用いて、AES暗号/復号の機能を作成しています。

AES_set_encrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_ENCRYPT)にて暗号、
AES_set_decrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_DECRYPT)にて復号するコーディングをしました。

(http://d.hatena.ne.jp/hnko/20090302/1235977892のenc_aes128_cbc_test()を参考にしましたので、
一連の流れは、こことほぼ同じです)

デバッグしてみると、一見、暗復号が問題なく出来ていたので、
AES_set_encrypt_key関数の第一引数のkey配列の値と、
ivec配列の値を変えて、デバッグしてみたところ、
key配列を変更すると、暗号化後の文字列も変更されますが、
ivec配列を変更しても、暗号後の文字列に変化が有りませんでした。

調べてみたところ、AES_set_encrypt_keyにて返される
AES_KEYのroundsの値が常に同じであることが原因と思われますが、
roundsの値が常に一定だと、暗号解読が比較的容易に
出来てしまうと思うのですが、上記で挙げたサイトでの
コーディングの他に、何か別にコーディングを足さなければならないのでしょうか?

よろしくお願いします。

VC++2008にてopensslを用いて、AES暗号/復号の機能を作成しています。

AES_set_encrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_ENCRYPT)にて暗号、
AES_set_decrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_DECRYPT)にて復号するコーディングをしました。

(http://d.hatena.ne.jp/hnko/20090302/1235977892のenc_aes128_cbc_test()を参考にしましたので、
一連の流れは、こことほぼ同じです)

デバッグしてみると、一見、暗復号が問題なく出来ていたので、
AES_set_encrypt_key関数の第一引...続きを読む

Aベストアンサー

>ivec配列を変更しても、暗号後の文字列に変化が有りませんでした。
初期ベクタを変えれば必ず暗号文が変化する筈。
変わらないとしたら、初期ベクタを変えているつもりで変わってないだけ。

因みに、初期ベクタは、1ブロック暗号化するたびに内容が更新されていくので、使い方を間違えないように。

>roundsの値が常に一定だと、暗号解読が比較的容易に
暗号鍵を変えればAES_KEYの内容も変化する筈。
変わらないとしたら、暗号鍵を変えているつもりで変わってないだけ。

Qerror C2440: 'static_cast' : 'CString' から 'LPCSTR' に変換できません

CStringから LPCSTR型への変換orその逆について教えて下さい。
Visal Studio 2005のC++で以下のサンプルを動かしました。

http://www.g-ishihara.com/mfc_nw_01.htm

すると、以下のプログラムを実行させると、IとIIでエラーが発生しました。

I  byteCP = static_cast<LPCSTR>(sendStr) +sendSum;

error C2440: 'static_cast' : 'CString' から 'LPCSTR' に変換できません。


II  byteP = recvStr.GetBuffer(21);
error C2440: '=' : 'wchar_t *' から 'LPSTR' に変換できません。


学習のため、サンプルに従って進めていきましたが、
そこでつまずいてしまいました。
CStringについては、全く知識がありません。
ご存じの方、教えて下さい。


void CClientSockDlg::OnBnClickedBtnSend()
{
CSocket sock;
unsigned int port = 0;
CString sendStr, recvStr;
int send, recv, sendSum, recvSum;
LPCSTR byteCP = NULL;
LPSTR byteP = NULL;
int err = 0;

UpdateData();

// (1)ソケット作成
if (!err) if (!sock.Create()) err = 1;
// (2)ポート取得
if (!err) if (_stscanf_s(m_xvEditPort, _T("%d"), &port) != 1) err = 1;
// (3)接続
if (!err) if (!sock.Connect(m_xvEditIP, port)) err = 1;
// (4)送信(20バイト固定)
if (!err)
{
sendStr = m_xvEditMes;
while (sendStr.GetLength() < 20) sendStr += _T(" ");
sendStr = sendStr.Left(20);

sendSum = 0;
while (sendSum < 20)
{
byteCP = static_cast<LPCSTR>(sendStr) +sendSum; //------- I
send = sock.Send(byteCP, 20 -sendSum);
if (send == SOCKET_ERROR) {err = 1; break;}
sendSum += send;
}
}
if (!err)
{
m_xvEditLog += _T("Send : ");
m_xvEditLog += sendStr +_T("\r\n");
}
// (5)受信(20バイト固定)
if (!err)
{
byteP = recvStr.GetBuffer(21);  //------- II
recvSum = 0;
while (recvSum < 20)
{
recv = sock.Receive(byteP +recvSum, 20 -recvSum);
if (recv == SOCKET_ERROR || recv == 0) {err = 1; break;}
recvSum += recv;
}
byteP[20] = '\0';
recvStr.ReleaseBuffer();
}
if (!err)
{
m_xvEditLog += _T("Recv : ");
m_xvEditLog += recvStr +_T("\r\n");
}
// (6)エラー表示
if (err)
{
LPVOID lpMsgBuf = NULL;

::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, sock.GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL);

m_xvEditLog += _T("Error : ");
m_xvEditLog += static_cast<LPTSTR>(lpMsgBuf);
UpdateData(FALSE);
LocalFree(lpMsgBuf);
}
// (7)切断
sock.Close();
UpdateData(FALSE);

return;
}

CStringから LPCSTR型への変換orその逆について教えて下さい。
Visal Studio 2005のC++で以下のサンプルを動かしました。

http://www.g-ishihara.com/mfc_nw_01.htm

すると、以下のプログラムを実行させると、IとIIでエラーが発生しました。

I  byteCP = static_cast<LPCSTR>(sendStr) +sendSum;

error C2440: 'static_cast' : 'CString' から 'LPCSTR' に変換できません。


II  byteP = recvStr.GetBuffer(21);
error C2440: '=' : 'wchar_t *' から 'LPSTR' に変換できません。


学習...続きを読む

Aベストアンサー

VC2005以降はUnicodeが標準でありwchar_tやwchar_t*を使うことになります
マルチバイト(シフトJIS)系を使用するのであれば

プロジェクト > プロパティ > 全般の中の
『文字セット』を『マルチバイト文字セットを使用する』に変更してみましょう

Unicode/マルチバイト双方でソースをいじらなくてもすむようにするなら
LPCSTRをLPCTSTR、LPSTRをLPTSTR
といった具合に双方で別々である型指定を統合するマクロを使いましょう

QLSI C-86試食版のコンパイルエラーが出ます:Undefined symbol : pow_

下記のC言語のプログラムでpow関数を使っていますが、コンパイル時にエラー(Undefined symbol : pow_)がでます.この原因をご教示いただけませんか。
LSI C-86試食版を使用しています。


#include <stdio.h>
#include <math.h>
int main(void)
{
double x;
double y;
double z;
x=2.3;
y=3.3;
z=pow(x,y);
}

Aベストアンサー

コンパイル時のオプションに -lmathlib を指定してください。
詳細は「LSI C-86 Ver. 3.30c試食版」の「■よく聞かれる質問と回答」を参照してください。
http://www.lsi-j.co.jp/freesoft/index.html

参考URL:http://www.lsi-j.co.jp/freesoft/index.html


人気Q&Aランキング

おすすめ情報