ストリームでのファイル操作

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

ストリームでのファイル操作

投稿記事 by zxc » 12年前

  割と苦戦してます。日本語では欲しい情報が少ないので英語読まなきゃいけなかったり、getlineはstringのものかistreamなのか間違っていたり、その二つで構文違って混乱したり。
  c_str関数はconst char*だからキャストで外してみた、が上手く動かないってどういうことだ・・・ いやstringの引数を認めるのかstringがconstでないものを返すべきかは知らないけど。
  とりあえず空白の行を無視したいかな。文字列は行ごとに取得して何やら操作できるのが望ましいか。
  外部ファイルの情報でプログラムを動かそうと思うのだが、どんな方法で外部ファイルを記述するべきかよく分からない。エクセル使わないけど紹介されているようにまとめるべきなんだろうか。因みに今回はキーコンフィグを想定。例外の練習も兼ねる。
  配列string用意して入れていく感じでいいのかな?動的確保になるからvector?空白行無視と、外部ファイルにある文字列が出たらループ終了やその行の読み取りは終わりとかやってみたい。xmlや他のスクリプト試したほうが速いかね。

CODE:


#include
#include
#include 

void open_check(const std::ifstream&,const char*);

int main(){


	std::ofstream log("log.txt");
	std::ifstream fs("test.txt");

	try{
		open_check(fs,"file opening error");
	}
	catch(std::iostream::failure &e){
		log(str2.c_str()) ,str2.size() );
		std::cout<<str2<<std::endl;//空白の行が生成される
		*/

		std::getline( fs , str2 );
		std::cout<<str2<<std::endl;

	}
	
	std::cout<<fs.cur<<std::endl;
	return 0;
}








void open_check(const std::ifstream &f,const char * error_mes){
		try{
			if(f.is_open() == 0){
				std::iostream::failure error( error_mes );
				throw error;
			}
		}
		catch(std::iostream::failure &e){
			std::cout<<e.what()<<std::endl;
			throw;
		}

}

結果:
start 0
select 1

right 2
left 3
down 4
up 5

button_circle 6
button_triangle 7
button_closs 8
button_square 9

button_rs 10
button_ls 11

button_rs2 12
button_ls2 13
button_rs3 14
button_ls3 15
1
続行するには何かキーを押してください . . .
読み取った.txtファイルどおり。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前

Re: ストリームでのファイル操作

投稿記事 by h2so5 » 12年前

constは書き込みを禁止するためについているものです。
その安全装置をconst_castで無理やり外して書き込もうものなら...

((((;゚Д゚))))ガクガクブルブル

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: ストリームでのファイル操作

投稿記事 by zxc » 12年前

  やっぱり外すべきじゃないですよね。しかしながらstringをchar*型に変換する簡単な方法思いつきませんでした。今のところ、>>演算子やfindでなんやかんやするか、ライブラリ等の力を借りるほうがよさそうと分かりました。外部ファイルについてもYAMLを教えていただき、ありがとうございます。
 

アバター
みけCAT
記事: 6734
登録日時: 14年前

Re: ストリームでのファイル操作

投稿記事 by みけCAT » 12年前

zxc さんが書きました:しかしながらstringをchar*型に変換する簡単な方法思いつきませんでした。
簡単かどうかは個人の感覚でしょうが、例えばこんな感じでしょうか?

CODE:

#include 
#include 
#include 

char* string2charptr(const std::string& str) {
	char* result;
	result=(char*)malloc(sizeof(char)*(strlen(str.c_str())+1));
	if(result==NULL)return NULL;
	strcpy(result,str.c_str());
	return result;
}
最後に編集したユーザー みけCAT on 2013年3月07日(木) 23:01 [ 編集 1 回目 ]
理由: バグ修正

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前

Re: ストリームでのファイル操作

投稿記事 by MoNoQLoREATOR » 12年前

>>しかしながらstringをchar*型に変換する簡単な方法思いつきませんでした。
みけCATさんのようにすれば良いと思います。
ただし使い終わったらfree関数を使って解放する必要があります。
よってmallocではなくnewを使用し、スマートポインタを活用することをおすすめします。

ちなみにfstreamでは日本語を含むディレクトリ下のファイルを扱うことができなかったと思います。
ですからファイルストリームクラスを自作することをおすすめします。
意外と簡単ですし、良い経験になると思うのでぜひやってみてください。

YuO
記事: 947
登録日時: 14年前

Re: ストリームでのファイル操作

投稿記事 by YuO » 12年前

zxc さんが書きました:しかしながらstringをchar*型に変換する簡単な方法思いつきませんでした。
関数内でC-likeなライブラリに渡すだけなら,

CODE:

std::string s;
// 処理
std::vector v(s.begin(), s.end));
v.push_back(0);
のようにstd::vector使うのも方法としてあります。
最後のpush_backをresizeにすることで,文字列追加にも対応できます。
また,特定の領域にコピーするのであれば,std::string::copyも使えます (最後に\0は追加されないので,自分で追加する必要があります)。
MoNoQLoREATOR さんが書きました:ちなみにfstreamでは日本語を含むディレクトリ下のファイルを扱うことができなかったと思います。
それは特定の実装に関わる話ですね。
std::fstream自体にそのような制限はありませんし,例えばVC++のstd::fstreamは扱えます。

wchar_tの配列で名前が取り扱えない,というのであれば,それは正しい指摘ですが,
それは日本語を含むディレクトリやファイルを取り扱えないことを意味しません。
# wchar_tが使えないために開けないファイルが存在するのは確か。

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前

Re: ストリームでのファイル操作

投稿記事 by MoNoQLoREATOR » 12年前

>>YuOさん
私は使えなくてデバッグにとても苦労した覚えがあります。
そのとき調べた際に「パスに日本語が含まれていると駄目だ」という記述を見つけたので今までそういう理解をしていましたが、まあ確かに日本語"だけ"が駄目だということは考えにくいですから、2バイト文字のことを言いたかったのだろうと思われます。
また、VCでは「Unicode文字セットを使用する」設定になっていない場合においてその問題が発生するそうです。
ソースはこのサイト
確かに根本的な原因は「ワイド文字」ということになりますね。

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: ストリームでのファイル操作

投稿記事 by zxc » 12年前

  色んな方法があるんですね、勉強になります。出来るだけ用意された機能を組み合わせる程度のことをやってみよう、ということで始めたので割と考えずにconst_castを使ってしまいました。あまり使ったこと無いので試しに使ってみたいと言うこともありましたが、使うべきではないですね。