fprintfでの改行文字出力に関して

[戻る]
8ビット 2003/11/14(金) 01:26:39
こんばんは。
ちょっと困っておりまして、なにかご存知のかたご教授願えますか。

fprintfで改行文字"\n"を出力したファイルに
余計な改行文字が出力されてしまい困っております。

たとえば下記のようなコードを実行した場合、

FILE* fp = fopen("C:\\test.txt", "w");
if(fp != NULL)
{
  string str("abc");
  fprintf(fp, "%s\n", str.c_str());
  fclose(fp);
}

ファイルには
----ファイルの中身の始まり-----
abc
EOF
----ファイルの中身のおわり-----
とはならずに
----ファイルの中身の始まり-----
abc

EOF
----ファイルの中身のおわり-----
と余計な改行文字が出力されてしまいます。

このソースを含むEXEファイルはWin2Kserver VC++SP5で
作成しました。実は作成した環境や、当方の周りのPCで
実行した場合は問題ないのですが、
遠く離れた顧客の環境では現象が発生するようです。

ちょっと前置きがながくなってしまって恐縮ですが、
WindowsのIMEや、各種設定などなんでもよいのですが、
このような現象が発生する手がかりがありましたらお教えください。

最後にですが、EXEファイルではsetlocaleは行っていません。

wood 2003/11/14(金) 06:17:01
FILE* fp = fopen("C:\\test.txt", "wb");
詳しくはMSDNみて

wood 2003/11/14(金) 07:10:59
↑デフォルトはテキストモードでopenされるため¥nが勝手につけられます
バイナリモードの場合変換作業等は一切されません、そのため自分で指定した
文字・コードなどは、そのまま書き込まれることになります

ししゃも 2003/11/14(金) 08:03:14
>↑デフォルトはテキストモードでopenされるため¥nが勝手につけられます

つきません
テキストモードのときは\nが\r\nに
(正確にゆうと、その環境での改行コードに)変換されます

問題が発生するというお客さんは
その現象を、どのように、チェックしたか聞いてみてください

もしくは問題が起こったその結果(ファイル)を送ってもらって
バイナリでみるツールなどで確認してみてください

ししゃも 2003/11/14(金) 08:12:01
もうひとつ

>↑デフォルトはテキストモードでopenされるため

違います
デフォルトの変換モードはグローバル変数 _fmode によって定義されます

ご自身の環境とお客さんの環境の _fmode をチェックしてみてください

ししゃも 2003/11/14(金) 08:13:50
あぁ、すいません、環境変数じゃないです< _fmode

プログラム中で何か代入していないかチェックしてください

επιστημη [E-Mail] [HomePage] 2003/11/14(金) 09:24:56
その'遠く離れた顧客'さんからtest.txtを'バイナリ'で送ってもらい、
*本当に*改行がダブっているか確認したのでしょうか?
Windowsで生成したテキストをUNIX/Linuxで読むと無駄な改行があるように見えたりします。

8ビット 2003/11/14(金) 10:33:11
みなさんありがとうございます。
おはようございます。すみません、会社の避難訓練で返答遅れました。

>テキストモードのときは\nが\r\nに
ネットで同様の情報を入手できました。Windows固有の仕様みたいですね。
(実はまったく知りませんでした。。)

実はサーバマシンで作成したCSVファイル(ご存知と思いますが、カンマ区切りで
データを列記したものです)をJAVAアプレットで読み込んで処理を行っており、
このJAVAアプレットはEOF以外のなにも出力されない行に対して処理を行うと
エラーになる仕様で、顧客環境ではこのJAVAアプレットのほうで
"ファイルの中身がエラー"になっております。

顧客に送付していただいたファイルをこちらでメモ帳で開きますと、
----ファイルの中身の始まり-----
abc,def,ghi
123,456,789

EOF
----ファイルの中身のおわり-----
のように表示されます。

また、昨夜簡単なソースをのせましたが、実際はCSVデータの要素数は決まって
いるので、下記のように出力しています。(へんなコーディングと思いますが、
とりあえずご容赦ください^^;)

vector<string> vec1;
vector<string> vec2;
 :
 vec1,vec2に要素を代入(vec1とvec2の要素数は同数)
 :
for(int i = 0; i < vec1.size(); i++)
{
  fprintf(fp, "%s,%s\n", vec1[i].c_str(),vec2[i].c_str());
}

>あぁ、すいません、環境変数じゃないです< _fmode
>プログラム中で何か代入していないかチェックしてください
プログラム中でとくに_fmodeに対してはなにも行っていません。
VC6.0をインストールしてから一度もいじっていません。

>その'遠く離れた顧客'さんからtest.txtを'バイナリ'で送ってもらい、
>*本当に*改行がダブっているか確認したのでしょうか?
バイナリで送ってもらうとは、圧縮などして送ってもらうことを
いっていますか? すみません、そうであればすぐそうします。

επιστημη [E-Mail] [HomePage] 2003/11/14(金) 10:43:33
>>その'遠く離れた顧客'さんからtest.txtを'バイナリ'で送ってもらい、
>>*本当に*改行がダブっているか確認したのでしょうか?
> バイナリで送ってもらうとは、圧縮などして送ってもらうことを
> いっていますか? すみません、そうであればすぐそうします。

いや、そーゆーことじゃなくて。

メモ帳なんかで開くのではなく、そのファイルの末尾にあるのが
一体なんであるのか確認したか? です。

8ビット 2003/11/14(金) 10:56:33
バイナリで表示するフリーソフトで表示してみました。
すると、私が想定している

abc,def,ghi[改行]
123,456,789[改行]

の改行のところには確かに"0D0A"となっていました。
0Dが"\r"で、0Aが"\n"ですよね。
で、ファイルの最後のところは確かに
"0D0A0D0A"となっています。また、EOFをあらわす"1A"は出力されていません。

8ビット 2003/11/14(金) 10:59:26
そもそもこちらで作成したプログラムのバグという線もありますが、
fprintf("%s,%s\n",
とカンマも記述しているので、改行だけ出力されることは
考えられないと考えているのですが。。

えっと 2003/11/14(金) 11:23:07
%sで表示しているデータ自体に改行が入っているとか
はありませんか?

その処理を行ったときは常にエラーになりますか?

8ビット 2003/11/14(金) 12:17:23
>%sで表示しているデータ自体に改行が入っているとか
>はありませんか?
そうですね。むしろその線を調査してみます。
ありがとうございます。

>その処理を行ったときは常にエラーになりますか?
Javaアプレットではエラーになります。

8ビット 2003/11/14(金) 19:30:53
原因判明いたしました。

顧客環境のデータ不正でありました。
データに改行文字が入力されていたため、改行されていました。
普通の運用をした場合はありえないケースだったのですが、
顧客が自分でDB登録したデータでありました。

貴重なお時間をさいて考えてくださったみなさん
ありがとうございました。

8ビット 2003/11/14(金) 19:31:27
[[解決]]
失礼いたしました。

古いスレッドには追加発言できません。