テキストを一文字読み込むときは、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と関連する良く見られている質問

QC++ の typedef の 使い方の質問

C++のtypedefの使い方の質問ですが、typedefは、別名の定義として、知られていますが。
以下のソースの意味がよく読み取れないです。windows プログラミングとC++
が分かるかたがいれば、以下のソースの意味を教えていただきたいです。

よろしくお願いします。
typedef BOOL (WINAPI *AddAccessAllowedAceFn)(
PACL pAcl,
DWORD dwAceRevision,
DWORD AceFlags,
DWORD AccessMask,
PSID pSid
);

Aベストアンサー

関数ポインタの別名定義です。
「関数ポインタ typedef」をキーワードにWeb検索してみてください。
丁寧に解説されているサイトが見つかるでしょう。

Qテキストを一文字以上ずつ読み込みたい。

通常テキストを一文字ずつ読み込む時って
cin.get(c)とか、やりますよね?
でも、二文字ずつ読み込む時ってどうやるんですか?
そもそもできるんでしょうか?
もしできないとしたら、それに相当する書き方とかあるんでしょうか?

Aベストアンサー

iostream(ていうかC++)はよく解らないのですが...

"stdio.h"に定義されているfgets()関数を使えばいいのではないでしょうか。
fgets(
char* 読込先の文字配列,
int 読む文字数+1,
FILE* 読み込むファイルポインタ);
です。

以下は使用例です。

#include <stdio.h>
int main(){
 char buf[5];
 FILE* fp;

 if((fp=fopen("C:\\aaaa.txt","ra"))==NULL){
  printf("ファイルのオープンに失敗.\n");
  return 0;
 }

 fgets(buf, 3, fp);
 printf("%s\n", buf);

 fclose(fp);
 return 0;
}

fopen関数でファイルのファイルポインタを作って
fgets()で二文字読み、表示してから
fclose関数でファイルポインタを無効にします。

配列を知らないって場合はちょっときついかもしれませんが...
ま、その際は補足要求をどうぞ。

iostream(ていうかC++)はよく解らないのですが...

"stdio.h"に定義されているfgets()関数を使えばいいのではないでしょうか。
fgets(
char* 読込先の文字配列,
int 読む文字数+1,
FILE* 読み込むファイルポインタ);
です。

以下は使用例です。

#include <stdio.h>
int main(){
 char buf[5];
 FILE* fp;

 if((fp=fopen("C:\\aaaa.txt","ra"))==NULL){
  printf("ファイルのオープンに失敗.\n");
  return 0;
 }

 fgets(buf, 3, fp);
 printf("%s\n", buf);
...続きを読む

QC++.NET の String型の使い方

初めて質問いたします。
C++ .NET 2005 Express Beta版を入手し、Windows Formsのプログラミングを勉強してます。

TextBoxのTextに値を変数で指定したいのですがどうすれば良いのかわかりません。

  textBox1->Text = "Test";
とダイレクトに値を指定すればできるのですが、

  #include <string>
  using namespace std;
   (省略)
  string str = "Test";
  textBox1->Text = str;
は、エラーになってしまいます。

C++標準のstringクラスではなく、.NETはStringクラスがあるようですが、これの使い方がMSDN等で調べているのですが分かりません。
分かりやすいURLなどありましたら教えていただけませんか。

Aベストアンサー

textBox1->Text = new String(str.c_str());
でいけるんじゃないかなあ。
試してないのでなんですが、
C++のstringクラスからは、c_str()で、いわゆるNULL終端文字列へのポインタが得られて
.NETのStringクラスは、NULL終端文字列でのコンストラクタがありますから。

Qプログラミングの問題で、キーボードからアルファベットの大文字を一文字読み込んで、その文字がAから数え

プログラミングの問題で、キーボードからアルファベットの大文字を一文字読み込んで、その文字がAから数えて何番目の文字であるかを表示するプログラムを作成の問題です
しかし、キーボードからは必ずアルファベットの大文字が入力されるものと仮定し、それ以外の文字が入力された場合や、2文字以上の文字が入力された場合の事は考えなくていいです
ヒントは、ASCIIコードでは、アルファベットの文字コードはアルファベット順に並んでます
作成できる方お願いします
c言語です

Aベストアンサー

いかのようにしてください。
#include <stdio.h>
int main()
{
int data;
int junban;
printf("アルファベットの大文字を一文字入力:");
data = getchar();
junban = data-'A'+1;
printf("入力された文字はAから%d番目です\n",junban);
return 0;
}

Qc++ stringの使い方

お世話になります。
最近c++始めました。
stringの使い方がよくわかりません。
以下のstringの使い方が問題ないか確認頂けますか。
スマホで書くため、文法が合ってないと思いますが、stringの使い方だけ確認させてください。
引数にstringで囲って渡すのは実装として普通行いますか。
やってはいけないですか。
是非ご教示ください。

#define STR1 "mojiretu"
main()
if(check(string(STR1)))



bool check(string str)

Aベストアンサー

間違っちゃいないけど、直に const string でかまわんのでは?

#include <iostream>
#include <string>

const std::string STR1 = "mojiretu";

bool even_length(const std::string& str) {
return str.length() % 2 == 0;
}

int main() {
if ( even_length(STR1) ) {
std::cout << STR1 << " : even\n";
} else {
std::cout << STR1 << " : odd\n";
}
}

Q特定の文字列をcsvから探して、その文字列を含む行を読み込むには?

例えば以下のようなcsvファイルがあったとします。

ab1,ef2,ab3,af4,ab5
bb1,bf2,bb3,bf4
cb1,cf2,cb3,cf4,cb5
zb1,zf2,zb3,zf4,zb5


プログラムに"cb3"という文字列を探させて、その文字列を含む一行
"cb1,cf2,cb3,cf4,cb5"のみを読み込む方法を探しております。

何か良い方法がございましたら教えていただけませんでしょうか?
よろしくお願いします。

Aベストアンサー

http://oshiete1.goo.ne.jp/qa5709184.html
でやった、fgets + sscanf を使うもう一つの利点は、同じ行に対して複数の処理を行うときに楽、ということです。

文字列の中にある文字列が含まれているか調べるには、strstr関数を使用するか、同等の処理を自作します。
strstrを使用する場合は、#include <string.h>を追加してください。
探す文字列が日本語の場合は、文字コードにも注意してください。

実際の例としては、前回のプログラムに下の+で始まっている行を追加してみてください

while( fgets( buf,600, fp ) != NULL ) {
+/* "cb3"が含まれていなかったら、次のループへ */
+ if ( strstr( buf, "cb3" ) == NULL ) {
+ cotinue ;
+ }
ret = sscanf( buf, " %[^,],%[^,],%[^,],%[^,],%s", s, n1,n2,f1,f2 ) ;

http://oshiete1.goo.ne.jp/qa5709184.html
でやった、fgets + sscanf を使うもう一つの利点は、同じ行に対して複数の処理を行うときに楽、ということです。

文字列の中にある文字列が含まれているか調べるには、strstr関数を使用するか、同等の処理を自作します。
strstrを使用する場合は、#include <string.h>を追加してください。
探す文字列が日本語の場合は、文字コードにも注意してください。

実際の例としては、前回のプログラムに下の+で始まっている行を追加してみてください

while( fgets( ...続きを読む

QVisial C++おけるπの使い方

自宅でCプログラミングの練習をするためVisial C++ 2008を使って
プログラムをしています。y<sin(πx)となった時の
割合などを計算するプログラムで                「M_PIが定義されていない識別子です」
とでてきます。所持している本を参考にしてもM_PI=πとして用いる
と書いてあり、math.hもインクルードしてるので原因が分からなくて
困ってます。Visial c++ではπの使い方には何か別の使い方がある
のでしょうか?よろしくお願いします。
*↓が実際に作ったプログラムです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main(void){
int i,n,count=0;
double x,y,r,error;

srand((unsigned)time(NULL)); /*乱数の初期化*/

printf("How many trials?");
scanf("&d",&n);

for(i=0;i<n;i++){
x=rand()/(RAND_MAX+1.0);
y=rand()/(RAND_MAX+1.0);

if(y<sin(M_PI*x)){
count++;
}
}

r=(double)count/n; /*キャスト演算子を使用*/
error=2/M_PI-r;

printf("Result is %f (Error: %f)\n",r,error);

return 0;
}

自宅でCプログラミングの練習をするためVisial C++ 2008を使って
プログラムをしています。y<sin(πx)となった時の
割合などを計算するプログラムで                「M_PIが定義されていない識別子です」
とでてきます。所持している本を参考にしてもM_PI=πとして用いる
と書いてあり、math.hもインクルードしてるので原因が分からなくて
困ってます。Visial c++ではπの使い方には何か別の使い方がある
のでしょうか?よろしくお願いします。
*↓が実際に作ったプログラムです。
#include ...続きを読む

Aベストアンサー

★アドバイス
・math.hをインクルードする前に『_USE_MATH_DEFINES』定数を define します。

#define _USE_MATH_DEFINES
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main( void )
{
 :
 return 0;
}
必ず include する前に定義して下さい。

Q改行までの一文字ずつのファイル読み込み

こんにちは。
C言語で現在ある入力ファイルを読み込んで計算し、
ファイルを出力するというプログラムを作成中なのですが、
ファイルを読み込む場合に、
改行までの値を一文字ずつ読み込むという作業をさせたいと思っています。
データは、
abc

defgh

ijk

.....

といった感じで入力されており、

while((c = fgetc(fp)) != '\n'){
fscanf(fp, "%c", &q[i]);
}

と書いたのですが、セグメント例外が出て強制終了してしまいます。
初歩的なことで申し訳ないのですが、教えていただきたいと思います。よろしくおねがいします。

Aベストアンサー

(1)fgetc() の時点でもう既に1文字データを読んでいるので、
fscanf() で'再度取得'することはできません。
q[i] には c の値をそのまま代入してください。

(2)i はインクリメントしなくてよいのでしょうか?

(3)行の終端 '\n' を検出して while を抜けた後、
printf 文などでそのまま表示させていませんか?
文字列 q[] の終端にヌル文字を入れる必要があります。
(q[]が予めゼロクリアされているのなら入れる必要はありません)

(4)それと、feof() でファイル終端をチェックしながらやった方がいいです。

オーバーフローを起こさない為に q[] には大きめの配列を確保してください。

char q[1024];
int i = 0, c;

while( !feof( fp ) )
{
  if( ( c = fgetc( fp ) ) == '\n' )
    break;
  q[i++] = c;
}
q[i++] = '0';

みたいな感じ。

(1)fgetc() の時点でもう既に1文字データを読んでいるので、
fscanf() で'再度取得'することはできません。
q[i] には c の値をそのまま代入してください。

(2)i はインクリメントしなくてよいのでしょうか?

(3)行の終端 '\n' を検出して while を抜けた後、
printf 文などでそのまま表示させていませんか?
文字列 q[] の終端にヌル文字を入れる必要があります。
(q[]が予めゼロクリアされているのなら入れる必要はありません)

(4)それと、feof() でファイル終端をチェックしながらやった方が...続きを読む

QcygwinでのC++の使い方

cygwinでC言語で書いたプログラムを実行したいのですがcygwinを起動すると
私の名前@なにやらアルファベット
が表示され次の行に

と表示されるんですがこの後にどんなことを書けば
#include<・・・>
としてC++のプログラムを書いていくことができるんですか?そもそもcygwinの使い方が根本的に違うんですかねえ?それともメモ帳かなんかにプログラムを書き保存しそれをcygwinで実行するんですかねえ?とりあえずプログラムを実行できるようにしてください。おねがいします。

Aベストアンサー

> それともメモ帳かなんかにプログラムを書き保存しそれをcygwinで実行するんですかねえ?

おおむねその通りです。

メモ帳でも何でもよいので、エディタでソースファイルを作成してください。作成したソースファイルは、とりあえずホームディレクトリに格納するとよいでしょう(C:\cygwinにCygwinをインストールしたのであれば、C:\cygwin\home\アカウント名がホームディレクトリになります)。

作成したソースファイルがfoo.cppだった場合、

g++ foo.cpp

とすれば、a.exeという実行ファイルが同じディレクトリにできるはずです。そこで、

./a

と入力すれば、a.exeを実行することができます。

QC++で、テキストファイルを一行ずつ読み込んで配列に入れたいのですが、

C++で、テキストファイルを一行ずつ読み込んで配列に入れたいのですが、うまくできません!

テキストには -3.0
       1.0
       2.0

・・・などのように一行に一つの数値が入って縦に並んでいます。
それをひとつずつ読み込み、新しい配列(たとえばa[])に順番にいれたいのです。

a[1]=-3.0,a[2]=1.0、・・・と
なるように。

どうか、この初心者にご指導お願いいたします。

Aベストアンサー

fgetsは文字列として読み込みます。これを数値に変換すれば、とりあえずあなたが望んでいることができます。変換はatofを使います。また、atofを使用するときは#include <stdlib.h>が必要です。
例えば
#include <stdlib.h>
  :
double d;
  :
d=atof("-3.0");
とすると、文字列の-3.0が数値の-3.0に変換されdに入ります。

fscanf関数で読み込んでもできますが、書式とデータがあっていないと上手くいかないので注意してください。


人気Q&Aランキング

おすすめ情報