ソースを貼り付けるため,長文になりますがよろしくお願いします。
Visual C++ 2008,Win32コンソールアプリケーションで作成。
今回質問したいことは,ファイルをオープンし,
配列に挿入したときに文字列の長さが一致しないことなんです。
**************************************************
//RLC.TRN(メモ帳で作成)
R1 1 2 10.0//空白は半角スペース1文字分
! //'!'がきたら終了
**************************************************
"R1 1 2 10.0"を配列に挿入します。
この配列を char cir_data[][] とします。
文字列の長さは"\0"文字を含めない"11"文字になるはずですよね?
ヘッダファイルは以下の通りです。
**************************************************
//Tran.h
#ifndef TRAN_H
#define TRAN_H
class Tran{
public:
int lp_cnt;
char cir_data[100][40];
void file_r();
};
#endif //TRAN_H
**************************************************
ファイルに関する関数は以下の通りです。
**************************************************
//file.cpp
#define _CRT_SECURE_NO_DEPRECATE 1 //警告抑制
#include "Tran.h"
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
void Tran::file_r(){
int i;
string filename("RLC.TRN");
FILE* fdi = fopen(filename.c_str(), "r");
for(i=0; ; ){
fgets(cir_data[i], 50, fdi);
if(cir_data[i][0] == '!') break;
if(cir_data[i][0] != '/') i++;
}
fclose(fdi);
lp_cnt = i;
/*******************************
確認用 実行結果
*******************************/
cout << cir_data[0] << endl;
cout << cir_data[1] << endl;
int len_cir0 = strlen(cir_data[0]);
int len_cir1 = strlen(cir_data[1]);
cout << "1行目の長さ = " << len_cir0 << endl;
cout << "2行目の長さ = " << len_cir1 << endl;
cout << "1行目の10文字目 = " << cir_data[0][9] << endl;
cout << "1行目の11文字目 = " << cir_data[0][10] << endl;
cout << "1行目の12文字目 = " << cir_data[0][11] << endl;
cout << "1行目の13文字目 = " << cir_data[0][12] << endl;
cout << "1行目の14文字目 = " << cir_data[0][13] << endl;
int len;
char s[] = "R1 1 2 10.0";
len = strlen(s);
cout << "本当の1行目の長さ=" << strlen(s) << endl;
}
**************************************************
メイン関数は以下の通りです。
**************************************************
//main.cpp
#include "Tran.h"
#include <iostream>
using namespace std;
void main(){
Tran RLC;
RLC.file_r();
}
**************************************************
これらをビルドすると,以下のような出力でした。
**************************************************
R1 1 2 10.0
!
1行目の長さ = 12
2行目の長さ = 2
1行目の10文字目 = .
1行目の11文字目 = 0
1行目の12文字目 = .
1行目の13文字目 =
1行目の14文字目 = フ
本当の1行目の長さ=11
続行するには何かキーを・・・
**************************************************
この結果で疑問なのは,なぜ余計な空白の行が入ってしまうのだろうということです。
そこで,文字列の長さを調べてみると,11文字のはずが12文字と出てしまいました。
次に,12文字目を調べてみると,やはりなぜか空白行が挿入されていました。
今後プログラミングを行う際,文字列をコピーしたり連結したりするので,
ここがはっきりしないと先に進めなくて困っています。
ヌル文字は12文字目にあるのか?13文字目にあるのか?
その場合12文字目には何が含まれているんだろう?
ファイルのオープンの仕方がまずいのでしょうか?
ピタっとデータファイルの1行目を11文字+"\0"という風に挿入するにはどうしたらいいのでしょうか。
長文失礼しました。よろしくお願いします。
すいません、訂正です。
出力結果の"1行目の12文字目 = ."
ではなく,"1行目の12文字目 = "(空白)です。
>ヌル文字は12文字目にあるのか?13文字目にあるのか?
>その場合12文字目には何が含まれているんだろう?
改行コードじゃないですか?
Windowsでは改行コードは'\r'と'\n'の2バイトになります。
バイナリエディタでそのファイルを開いてみたり、読み込んだ内容を16進数で表示してみたりしては?
瀬戸っぷさん,回答ありがとうございます。
バイナリエディタで開いてみたら,
0D 0A という改行コードが書きこまれていました。
調べたら,メモ帳で改行する際にOSが勝手に書きこんでしまうらしいとのこと。
ファイルを開いたときに改行コードまで文字列に挿入したくないのですが,
そのような方法がありましたら教えてください。
というかfgetsの結果に'\n'が付いているだけなのでは?
(\r\nは関係ない。fopenでテキストモードで開けは\rは勝手に取られる。)
> fgets(cir_data[i], 50, fdi);
の直後に
char* pLF = strchr(cir_data[i], '\n');
if (pLF != NULL) {
*pLF = '\0';
}
というように'\n'が末尾についていたら'\0'に書き換えるという記述を加えておくとか。
Blueさん,回答ありがとうございます。
上記のプログラムを追加したら,期待通りの動作をしてくれました。
\nに出会うまでと思っていたら,\nも含んでしまっていたんですね。
おかげ様で先に進めます。ありがとうございました。
解決しました。
ツイート | ![]() |