テキストを一文字読み込むときは、cin.get(c)
と、やりますが、二文字ずつ読み込む方法が分かりません。
cin.read(pch,2)とやればいいという事らしいんですが、これもよく分かりません。
どなたか教えてください。

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

A 回答 (4件)

こんにちは。

itohhといいます。

標準入力から2バイトずつ読みとりたいとのことですね?

サンプルを載せておきます。

#include <memory.h>
#include <string.h>
#include <stdio.h>
#include<iostream.h>

int main()
{
  char pch[3];
  
  memset(pch, 0x00, sizeof(pch) );
  
  cout<<"Input!\n";
  
  do
  {
    // NULLクリアしてから2バイト読み込む
    memset(pch, 0x00, sizeof(pch) );
    cin.getline(pch,3);
  
    cout<<pch<<'\n';
  }
  while(strlen(pch) == 2);

  return 0;
}

サンプルの説明をします。
各行の先頭には全角スペースを入れてインデントしていますのでコピペするときは
気をつけてください。
標準入力関数(cin)から帰ってくるタイミングはEnterキーを押下した場合です。
この前回答したcin.read関数よりcin.getline関数のほうが便利でした。すみません!
pchは、毎回、先頭から設定されますから配列数は3でOKです。

do whileループは、ループの最後に条件を判定します。

while(strlen(pch) == 2);
は、「読み込んだ文字列が2バイトの間、ループしなさい」という条件です。
なぜこの条件で良いのかというと漢字を入力していく場合、2バイトで1文字となりますが
半角の英数字を入力した場合で奇数バイトの入力を行ったとき、最後にpchに設定される文字
は1バイトとなります。(以下の例では[7]だけとなる)
ただし、2バイト文字(漢字)と1バイト文字(英数字)を混在して入力した場合は、2バイ
ト文字がばらばらになる可能性がありますので気をつけてください。


例えば、以下のように実行した場合。
>test
Input!
1234567   <---7の次にEnterキーを押下。
12
34
56
7


>
という結果になります。

最後に。
>標準入力から読み込むときとファイル指定する場合とではどのように違うんですか?
標準入力では、オープンすることはプログラムを実行した段階で自動的に行ってくれます。
しかし、ファイルから入力する場合は、プログラム内で明示的にファイルを指定してオープン
しなければ行けません。また、クローズも同様です。

この回答への補足

本当にくわしい御回答ありがとうございます。
結局、2バイトと考えて二文字読みとって行ってるということなんですよね?それでは、100文字ずつ読みとるならば
cin.getline(pch,100)としたらいいんですね!!解決しました。

ところで、図々しいようですが、もうひとつ・・・。
たとえば、二文字ずつ読みとっていって、それが特定の二文字、たとえば、
「gc」とかがでてきたら、それをカウントしていきたいんですけど、
そのときに、
if(pch=='gc')
count[1]++;
というふうにかくと、エラーになってしまいます。一文字のときは大丈夫なのになぜ二文字だとだめなんですか?

すいません。時間がありましたらで結構なんで、教えていただければうれしいです。

補足日時:2001/11/21 15:46
    • good
    • 0

横槍気味の回答になりますが。



>if(pch=='gc')
これは、"string.h"のstrcomp関数を使います。
この場合なら、
if((strcomp(pch,"gc"))==0)
です。
この関数は文字列を比較する関数で、二つの文字列が一緒なら0を返します。

>一文字のときは大丈夫なのになぜ二文字だとだめなんですか?
一文字(半角の)なら、単純にASCIIコードの数値で比較すればオッケーですが、
二文字以上になると数値でってわけに行かなくなるからです。
それから「'(シングルクォート)」は、一文字のコードを表すものです。
例えば'A'はASCIIコードなら65と書いたのと同じことになります。
この場合の「二文字以上がまずい」のはそのせいでもあります。
    • good
    • 0
この回答へのお礼

非常にわかりやすい御回答ありがとうございました、
お二人には今回非常に有益な回答をしてもらって感謝いたしております。
また、わからないことがあったらここに質問したいと思います。
それにしても、プログラムは奥がふかいですね。
もっと、勉強していきたいです。

お礼日時:2001/11/22 17:54

こんにちは。

itohhといいます。

fatal_errorさんありがとうございます。
わたしも解決したのか気になっていました。

cinを使うと言うことは標準入力から(DOS窓でキー入力など)から読み込むと
解釈してお答えしました。

質問者のyabuchanchanさんにお聞きしたいのですが、
A.ファイルを指定して読み込みたい。
B.標準入力から読み込みたい。

もし、Aならfatal_errorさんが回答しているような方法もアリだと思います。
でも、わたしなら、2バイト(2文字?って2バイトのことですよね。)づつ読み込まないで
まとめて読み込みます。CFileクラスやCStdioFileクラスなどを使用します。
なぜなら、その都度ファイルのアクセスするのはレスポンスが悪くなるからです。

この回答への補足

お返事ありがとうございます。標準入力から読み込むときとファイル指定する場合とではどのように違うんですか?

補足日時:2001/11/20 17:36
    • good
    • 0
この回答へのお礼

お返事、ありがとうございました。
とりあえず、以下のように書くと実行できました。
#include<iostream.h>
int main()
{
char pch[100];
cout<<"Input!\n";
while(pch)
{
cin.read(pch,2);
cout<<pch<<'\n';
}
return 0;
}

でも、ある一定以上の文字をキーボードから入力すると実行できなくなってしまいます。
これはどうしてなんですか?比較的大量のデータを扱いたいんですが・・。

お礼日時:2001/11/20 19:52

この質問、本来は先の質問で回答されたitohh氏に対して補足すべきかと思いますが...



この場合はcinよりも
"fstream.h"中のifstremの方が適切ではないでしょうか。
char型の配列(要素数3以上)に二文字ずつ読み込むのなら、

char pch[3];
とでもしておいて
ifstreamのread(pch,2)を呼べばいいと思います。

pchには最初ごみが入っているので表示までに
pch[2]=0;
しておかないと表示がバグりますが。

以下、使用例です。

#include <iostream.h>
#include <fstream.h>

int main(){
char pch[3];

ifstream readFile("c:\\test.txt");
readFile.read(pch,2);

pch[2] = 0;
cout << pch << endl;
return 0;
}

一応、コンパイルして動作確認済みです。

二文字ずつ読み込みたいなら、
while文で繰り返せば良いでしょう。

配列って何?とかいう場合は補足をどうぞ。

この回答への補足

レスありがとうございます。そうですね。まずitohhさんに対してするべきですね。でも、ポイント発行しちゃったんで、順番まちがえました。
さて、御回答いただいた内容ちょっとじっくり考えてみたいと思います。
それからまたレスさせていただきたいとおもいます。

補足日時:2001/11/18 17:30
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

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

QC++:cinが上手く使えない

 そもそもcinについてあまり詳しい事は知らないのですが
よろしくおねがいします。
 cinを使って整数を取りこもうとする時、数字以外が
入ってしまうとおかしな動作をします。

 例えば「10未満の整数値を取りこむまで続くループ」で
入力部分を作ろうとした時に、

while(1){
 cout << "入力してください" << endl;
 cin >> int_a;
 if(int_a < 10) break;
}

大体 以上の様に書くと、入力する時にアルファベットが
入ってしまうと

入力して下さい
入力して下さい
…(エンドレス)…
入力して下さい

となってしまいます。cinをあきらめてscanfにしてみると
今度は実行時エラーがでてしまいます。
 整数を入力する事が出来て、なおかつアルファベットが
入力されても' 'で囲った値が入るようにするには
どのようにすればよいでしょうか?

Aベストアンサー

失礼しました
1でしているような
エラーのクリアとデータの破棄を忘れていました

#include <iostream>
using namespace std;

void main(void)
{
int int_a;

while(true)
{
cout << "入力してください" << endl;
cin >> int_a;
if(cin.good()==0)
{
cout<<"変なものを入力しないでください"<<endl;
cin.clear();
cin.seekg(0);
break;
}
cout<<int_a<<"が入力されました"<<endl<<endl;
if(int_a < 10) break;
}
}

QEnterキーを押されたら次の処理に移るという事をしたい。

コンソールアプリケーション上で文字列を表示させた後、ユーザーがエンターキーを押したら次の文字列を表示するという仕様にしたいのですが、エンターキーだけ入力待ちにするっていうのはどのように書けばいいんでしょうか?

Aベストアンサー

#include <stdio.h>

int main(void)
{
char *str[] = {"abc", "def", "ghi", "jkl"};
int i;

for(i = 0; i < 4; i ++){
while(getchar() != '\n') ;
puts(str[i]);
}
return 0;
}

Qfgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

Aベストアンサー

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.
末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qprintf で二進表示を行いたい。

すみません。教えていただきたいことがあります。
printf で普通のintの値をフォーマット指定子を使用して二進表示をしたかったのですが見当たりませんでした。
どうにかintの内容を二進で確認したいのですが、どのようにすれば良いですか?
宜しくお願いします。

Aベストアンサー

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if ( value & bit ){
  putchar('1');
 }
 else{
  putchar('0');
 }
}
printf( " です。\n" );

最後に:
・1バイトが 8 ビットの環境が前提です。→まぁ、普通は 8 ビットですが…。
・上記のサンプルを関数などにすれば使いやすくなります。→print_bin()など
・以上。おわり。

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QC++で空Enterの入力を判断したい!!

空エンターで制御したい処理があるのですが、
char in[128];
gets(in);

if(in[0]=='n')
↑の判定だとif文に中に入ってくれません。
入力なしでもOKな様にgetsを使ってみました。
(ちなみにこのinには値が入ることもあります。)
enterの入力は改行コードが入るわけではないのでしょうか?
その場合どのように判定すればいいのか教えてください!
お願いします!!

Aベストアンサー

ランタイムライブラリの仕様を確認しましょう

VC++ですと getsで入力された文字列は最初の改行文字'\n'までがバッファに格納され '\n'を NULL文字の'\0'に変換する
となっているようです

判定の方法として

gets( buf );
if ( buf[0] == '\0' ) {
  // 空行の場合の処理
}
といった具合でしょう

Qscanf("%s", buf);でスペースを含んだ文字

コンソールプログラムで
scanf("%s", buf);
を使用してユーザに入力された文字によって処理を行いたいのですが、このままではスペースを含む文字列がスペースの手前で切られてしまいます。
C:\Program Filesなどを入力可能にさせたい場合にはどのようにするのがベターですか?

Aベストアンサー

お任せください!
そもそもscanfを使うというのはお勧めでは
ありません。scanfは文字+改行文字が入力
されないと完了しないためです。
が、それは良しとしましょう。
scanfの書式ですが、

int n = scanf("%[^\r\n]",buf);

という便利な書式があります。
perlでもおなじみの書式ですね。
上記の山文字"^"より前が読み込ませたい文字の集まりで、ハイフン指定が出来ます。
"^"より後ろが読込みを停止させたい文字の集まりです。上記の指定は復帰改行以外の文字が現れるまで読み込みます、という書式です。
下記のような指定も出来ます。

int n = scanf("%[a-zA-Z0-9\\: \t^\r\n]",buf);

なお、戻り値は読み込んだ項目数ですので、
if(n >= 1)
{
}
で判断できますね。

Q複数テキストファイルを読み込み、複数テキストファイルの出力

質問は100個のテキストファイル(それぞれ10個のデータを含む)を読み込み、それぞれのテキストファイルから5個ずつデータを抽出し、200個のテキストファイルとして出力するというプログラムについての質問です。
以下が僕の作ったファイル出力部分のプログラムです。

/************/

void ecg_rr(fp,data_max)

FILE *fp;
{
int b,i=0;
int c=1;
char fname[64];

data[0][i]=trend_data[0][i];

for(i=0;i<100;i++)

sprintf(fname,"ss[%d].txt",1+i);

fp = fopen(fname,"w");
fprintf(fp,"%4d\n",c);
fprintf(fp,"%8.8f\n",data[0][0]);
fprintf(fp,"%8.8f\n",data[0][2]);
fprintf(fp,"%8.8f\n",data[0][4]);
fprintf(fp,"%8.8f\n",data[0][6]);

fclose(fp);

sprintf(fname,"sk[%d].txt",1+i);

fp = fopen(fname,"w");
fprintf(fp,"%4d\n",c);
fprintf(fp,"%8.8f\n",data[0][1]);
fprintf(fp,"%8.8f\n",data[0][3]);
fprintf(fp,"%8.8f\n",data[0][5]);
fprintf(fp,"%8.8f\n",data[0][9]);

fclose(fp);


}

複数ファイルの読み込み方がわからず、自分のプログラムだと1つのテキストファイルしか読み込めないので、16_4.batを作り、その中身を
16_4 読み込むテキストファイル名1.txt ss[1]
16_4 読み込むテキストファイル名1.txt sk[1]

16_4 読み込むテキストファイル名2.txt ss[2]
16_4 読み込むテキストファイル名2.txt sk[2]
・・・
とやったのですが、うまくいきませんでした。
どうすればよいのでしょうか。

質問は100個のテキストファイル(それぞれ10個のデータを含む)を読み込み、それぞれのテキストファイルから5個ずつデータを抽出し、200個のテキストファイルとして出力するというプログラムについての質問です。
以下が僕の作ったファイル出力部分のプログラムです。

/************/

void ecg_rr(fp,data_max)

FILE *fp;
{
int b,i=0;
int c=1;
char fname[64];

data[0][i]=trend_data[0][i];

for(i=0;i<100;i++)

sprintf(fname,"ss[%d].txt",1+i);

...続きを読む

Aベストアンサー

>read_dataの呼び出しは上位レベルのものを直接
>sprintf(fname,,"ss[%d].txt",1+i);
>の後に代入すればよいでしょうか?
私には、上位レベルがどうなっているのかわかりませんので、判断がつきませんが、その前の方がいいと思います。
例:
for(i=0;i<100;i++)

sprintf(fname,"読み込むテキストファイル名%d.txt",i+1);
fp=fopen(fname,"r");
read_data(fp); /* リターン値を使う必要あり? */
fclose(fp);

sprintf(fname,"ss[%d].txt",1+i);

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング