空白を含む文を10文字ずつ読み出そうとしています。でも
文1:I am a poor programmer.
文2:2nd Sentence
結果:2nd Sentenr programmer.
となります。"I am a poo"が欲しいのですが。
800文字以内にするためにmainだけにしました。後で補足できます。
int main()
{
sentence sntc;
fstream file;
file.open("SENTENCE.TXT", ios::app | ios::out | ios::in | ios::binary );
sntc.getData();
file.write( reinterpret_cast<char*>(&sntc), sizeof(sntc) );
file.seekg(0, ios::end);
int endposition = file.tellg();
int n = endposition / sizeof(sentence);
cout << "\nThere are " << n << " sentences in file";
cout << "\nEnter sentence number: ";
cin >> n;
int position = (n-1) * sizeof(sentence);
file.seekg(position);
file.read( reinterpret_cast<char*>(&sntc), sizeof(sntc) );
sntc.showData();
cout << endl;
file.seekg(position, ios::cur);
file.read( reinterpret_cast<char*>(&sntc), 10);
sntc.showData();
cout << endl;
return 0;
}
No.3ベストアンサー
- 回答日時:
ひさしぶりにストラウストラップ本を見返してみました。
やはり、readでは\0が付加されないようです。
(『プログラミング言語C++第3版』§21.3.4)
seekgの前でちゃんと表示されたのは、ファイルからではなく、
getData()によって入力されたからでしょう。
この場合、自動的にヌルが付加されます。
ファイル読み込みに、read()ではなく、
getline()を使うと良いと思います。
ただ、やっぱりこのキャストはおかしい。
こうやって入力すると、たまたまsentence内のstrに
データが入るかもしれませんが、
オブジェクトの使い方としてはいただけません。
代案として、
(1)strをpublicにして、
file.getline(sntc.str, 11);
のようにする。
(2)バッファを使い、sentenceにsetStr, getStrメソッドを付加して、
char buf[80];
file.getline(buf, 11);
sntc.setStr(buf);
のようにする。
これ以上はわからないので、
C++に詳しい人の登場を待ちます。
解決しました!
一つ目の問題は私の「テストで表示」がいけなかったみたいです。
あの行のお陰で「本番の表示」のときには既に駒が一つ進んでました。
二つ目の問題はどうも
//file.seekg(position, ios::cur);
の行が邪魔をしていたようです。
下の通りに修正しました。
int main()
{
sentence sntc;
fstream file;
file.open("SENTENCE.TXT", ios::app | ios::out | ios::in | ios::binary );
sntc.getData();
file.write( reinterpret_cast<char*>(&sntc), sizeof(sntc) );
file.seekg(0, ios::end);
int endposition = file.tellg();
int n = endposition / sizeof(sentence);
cout << "\nThere are " << n << " sentences in file";
cout << "\nEnter sentence number: ";
cin >> n;
int position = (n-1) * sizeof(sentence);
file.seekg(position);
for(int i=0; i<5; i++)
{
position = file.tellg();
cout << position;
//file.seekg(position, ios::cur);
file.read( reinterpret_cast<char*>(&sntc), 10);
sntc.showData();
cout << endl;
}
return 0;
}
オリジナルの文は
"I am on my way to becoming a great C++ programmer."で
結果はこんな風です。
0
Sentence: I am on myB
10
Sentence: way to beB
20
Sentence: coming a gB
30
Sentence: reat C++ pB
40
Sentence: rogrammer.B
Press any key to continue
(Bがついていますが…気にしないでください(~o~))
結局、readとreinterpret_cast<char*>はそのままなのですが
getlineの発想から何がおかしいか発見できました。
liar_adanさんの回答がなかったらここまで辿り着けなかったと思います。
なるべく自分で解くように努力しますが、躓くだろうことは必至ですから
これからもどうかよろしくお願いします。m(__)m
ありがとうございました。
No.2
- 回答日時:
う~~ なんてこったい。
せっかく朝、新規の質問2つに解答を書いて、その後を楽しみにして覗いてみたら、2つとも消えてるではないですか。(これは質問者に言っているのではないですよ。
あくまでも管理人さんのほうです)
C++については良く分かりませんが、
1.コード1行づつに何をやってるのか書いてもらえればどこがおかしいか分かると思いますよ。
2.>結果:2nd Sentenr programmer.
>となります
推測ですが、1回目の読み込みのデータが残っているわけだから、それがあなたの期待に反するC++の仕様なら、自分で1回目のデータを消してから、2回目のデータを読み込めば良いのではないでしょうか?
答えてくださってたんですね。
どうやら、私の目に留まる前に消えたみたいですね。(>_<)
1. もともとのプログラムには一行一行丁寧に説明がありましたが、800字以内に収めないとここに載せられないので割愛しました(これが#1で述べている連続した質問をした理由です)。
2. それは確かに気付きませんでした。それで早速やろうと思ったのですが…クリアする方法が分かりませんでした。もうこの教科書、駄目です。5cmくらいの厚さがあるんですが、例題も目録も使えません。それ以前に私が駄目駄目ちゃんなんですが(爆)
ありがとうございました。
No.1
- 回答日時:
新しい質問が削除されてしまったようですね。
最近、規則が厳しくなって、
連続している質問は禁止されたんですよ。
で、私はCはちょっと自信がありますが、
C++はよく知りません。
見当で書きますが的はずれだったらごめんなさい。
問題は、file.read()で、10文字読み込んだところで
ヌル文字が書き込まれないことではないでしょうか。
char *による文字列は終端に\0が付かないとそのまま続いてしまいます。
10文字読み込んだ後に、11文字目に'\0'を書き込む作業が必要になります。
ところで、sentenceというのはどうもクラスのようですが、
これにreinterpret_castを使って文字列を書き込むのは、
どう考えてもおかしいような気がします。
クラスのメンバとしてchar txt[100];のようにして、
file.read(sentence.txt, 100);
とか
file.read(sentence.txt, 10);
とかする方が普通ではないでしょうか。
もう一度言いますが、私はC++は詳しくないので、
間違ったことを言ってるかもしれません。
お許しください。
はい、連続している質問は禁止されたのは知っていましたが、そうでもしないとC++のプログラムなんかは全部載らないんですよね。かといって削ると「質問が分からない」と過去に何度かケチつけられましたし…。それならば800文字の制限をなんとかしてもらいたいですよね、OKWebさん...。
でもliar_adanさんが回答下さったお陰でmain以外のパートもやっと公開できます。感謝します!
#include <fstream>
#include <iostream>
using namespace std;
class sentence
{
protected:
char str[80];
public:
void getData()
{
cout << "\n Enter a sentence: ";
cin.get(str, 80, '\n');
}
void showData()
{
cout << "\n Sentence: " << str;
}
};
問題は大きく分けて二つです。
・一つ目は"2nd Senten"ではなくて"I am a poo"の10文字を表示させたいこと。
positionの設定がおかしいと思うのですが(n-1)にした時点で0になってるはずですよね…。
なぜ最初からにならないのでしょうか?
・二つ目は10文字で終わらずに表示されてしまうこと。
そうですね、ヌルがいるかもしれませんね。
ただ、seekgの前のラインでテストのために文1を表示しているのですが、
ここではヌルがなくてもちゃんと文の終わりで終わってるんですよね…。
どうしても駄目なら自分でヌルを入れることにします。
実はこのプログラムは教科書に載っている例題をいろんなところから切り貼りして名前を変えて作りました。reinterpret_castは一度変えたらエラー(char *に変換できません、とかいう)を食らったので変えるのをやめました。本当に必要であれば変えてみます。
ありがとうございました。
…引き続き、回答をお待ちしております。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- その他(プログラミング・Web制作) pythonのエラーについて 2 2022/08/17 17:17
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- Windows 8 iOS や Winows で使われているAccountの考え方がいまいち分かりません。これはLinu 2 2022/04/28 22:05
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
文字列をカウントする方法
-
ファイル全てを .xlsm に変更し...
-
csvファイルの横方向への改行に...
-
MATLABのm-fileについて
-
WindowsでPerlをする際,1行目の...
-
Perl の「stringify」の意味に...
-
AutoNts
-
ファイルの存在の有無を確かめ...
-
一定時間が経過したフォルダの削除
-
while(<ハンドラ>) {} で行数を...
-
画像アップロード機能を追加し...
-
batファイルでrenameができませ...
-
while文がうまく動かない
-
VBAでCSVファイルの特定行を書...
-
配列のサイズを動的に拡張
-
ディレクトリのファイル作成を...
-
ANSI Cでファイル名、ディレク...
-
VB6.0でDB接続する際に切断時の...
-
Pythonの再帰関数の動作の流れ...
-
AutoCADのスクリプト
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
window.open でのファイル指定方法
-
csvファイルの横方向への改行に...
-
python renameについて
-
VBAコードを張り付け後のエクセ...
-
ファイルの存在の有無を確かめ...
-
行を指定して削除する方法PERL
-
VBA テキストファイルを読み取...
-
ファイル全てを .xlsm に変更し...
-
Firefox で file:// で始まる U...
-
fgets で値が取得できない
-
perl ファイルが開かない
-
MATLABのm-fileについて
-
Perl の「stringify」の意味に...
-
PerlでのUseless use...
-
JSP URLに表示される拡張子 .jsp
-
巨大なテキストの最終行を取得...
-
複数ファイルを1つにするシェ...
-
drtファイルはどうしたら開...
-
fopen64について
-
perlで画像をダウンロードしよ...
おすすめ情報