ifstream::getlineによるファイル処理 – プログラミング – Home

通知
すべてクリア

[解決済] ifstream::getlineによるファイル処理


瑞穂タン
 瑞穂タン
(@瑞穂タン)
ゲスト
結合: 17年前
投稿: 5
Topic starter  

宜しくお願い致します。

ifstream::getlineでファイルから一行づつ変数に格納しながら読みこませていましたが
データの仕様が変更になり文字のある行とEOFの間に改行が入ってしまい
その行に対しても処理を行ってしまうのでアクセスバイオレーションが発生してしまいま
す。
改行だけの行でループを終了する良い方法はございませんでしょうか。

whileの中で
if( line == " )
break;
とか
if( line == \n )
break;
などと試してみましたが失敗しました

・データ仕様
変更前
abc,def,ghi
jkl,nmo,pqr
EOF

変更後
abc,def,ghi
jkl,nmo,pqr

EOF

・ファイル読み込み処理
ifstream ifs;
ifs.open( foo.txt, ios::in );
char line[1024];
memset( line, 0, MAX_PATH );
while( !ifs.eof() ) {
ifs.getline( line, sizeof( line ) );
token = strtok( line, demil );
~省略
}

VS2005 C++


引用未解決
トピックタグ
アキラ
 アキラ
(@アキラ)
ゲスト
結合: 23年前
投稿: 49
 

\r\nじゃないですか?


返信引用
瑞穂タン
 瑞穂タン
(@瑞穂タン)
ゲスト
結合: 17年前
投稿: 5
Topic starter  

アキラさんこんにちは
ごめんなさい間違えました
改行のエスケープシーケンスコードは\r\nだったですよね
しかし
if( line == \r\n )
break;
試してみましたがスルーしてしまいました。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

char[] と 文字列リテラルを == で比較したのがマチガイの始まり。
std::string line 使えばいいのに。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>

using namespace std;

int main() {
ifstream ifs(foo.txt);
string line;
while( getline(ifs,line) ) {
if ( line.size() == 0 ) break;
cout << '[' << line << ] -> /;
char buf[1024];
strcpy(buf, line.c_str());
for ( char* p = strtok(buf,,);
p; p = strtok(0,,) ) {
cout << p << '/';
}
cout << endl;
}
}


返信引用
瑞穂タン
 瑞穂タン
(@瑞穂タン)
ゲスト
結合: 17年前
投稿: 5
Topic starter  

επιστημηさんこんにちは
std::string line;
getline( ifs, line );
としたら動きそうなのですが
token = strtok( line.c_str(), demil );
としてstring型を* char型にして切出すと
error C2664: 'strtok' : 1 番目の引数を 'const char *' から 'char *' に変換できま
せん。
と怒られてしまいます。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

はい、怒られます。それで?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> token = strtok( line.c_str(), demil );

token = strtok( &line[0], demil );
ならいけそうですが、'\0'終端されている保証がないのでお薦めしかねます。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

↓おそらくこれでいぃんじゃないかと。

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>

using namespace std;

int main() {
ifstream ifs(foo.txt);
string line;
while( getline(ifs,line) ) {
if ( line.size() == 0 ) break;
cout << '[' << line << ] -> /;
line += '\0';
for ( char* token = strtok( &line[0],,);
token; token = strtok(0,,) ) {
cout << token << '/';
}
cout << endl;
}
}


返信引用
アキラ
 アキラ
(@アキラ)
ゲスト
結合: 23年前
投稿: 49
 

簡単にまとめるとこんな感じかな
・char配列よりもstd::stringを使いましょう
・std::stringを返すgetlineがあります
・getlineで返ってくるstringには改行文字(\r\n)が含まれないので
 string::size()もしくはstring::length()で長さ0で「改行のみの行」を判定すればい


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

strtok は元文字列を破壊するわけだけど
basic_string って非メンバ関数経由で中身を壊して平気だっけ?


返信引用
瑞穂タン
 瑞穂タン
(@瑞穂タン)
ゲスト
結合: 17年前
投稿: 5
Topic starter  

επιστημηさん
おおきにありがとう

επιστημη [HomePage] 2008/03/03(月) 09:23:39
のレス見落としてました、このコードで動きました
strcpy(buf, line.c_str());
これでconstから開放されたんですね初歩的なボケでした
すんませんでした。

後この場をお借りして申し訳ないんですが
επιστημηさんの東方算程譚を時々ROMらせて貰っているんですが
最近記事が多くなりすぎて、探すのになんぎすることが多いので
検索エンジン付けてもらえたら助かります。


返信引用
瑞穂タン
 瑞穂タン
(@瑞穂タン)
ゲスト
結合: 17年前
投稿: 5
Topic starter  

あ!
また読み飛ばしてました
アキラさん
tetrapodさんもおおきにありがとう。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> strtok は元文字列を破壊するわけだけど
> basic_string って非メンバ関数経由で中身を壊して平気だっけ?

実質問題ないようです。イヤならcopyしろ、ですね ^^;

> 後この場をお借りして申し訳ないんですが
僕とこでやってください。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました