@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

テキストファイルのタブ区切り

投稿者投稿内容
Beginner
会議室デビュー日: 2004/02/06
投稿数: 17
投稿日時: 2004-02-10 14:01
タブ区切りで保存してあるテキストファイルを
ReadLine()で読み込み、タブ区切りごとの文字列を
それぞれの変数に取り出すにはどうしたらよいでしょうか?

よろしくお願いします。
Beginner
会議室デビュー日: 2004/02/06
投稿数: 17
投稿日時: 2004-02-10 15:50
先ほどのご質問のタブ区切りを取り出すのは出来たのですが、
もし、入力にタブを使うとうまく保存できないです。

public struct TKoji
{
public int KojiID;
public string KojiName;
}

ArrayList alKoji = new ArrayList();
TKoji koji = new TKoji();


private void readKojiList()
{
Encoding FILE_ENCODING = Encoding.GetEncoding("Shift_JIS");

try
{
string listName;

if (File.Exists(FILEPATH_KOJILIST))
{
StreamReader srList = new StreamReader(FILEPATH_KOJILIST, FILE_ENCODING);
while ((listName = srList.ReadLine()) != null)
{
string[] n = listName.Split(new char[]{'\t'});
koji.KojiID = Convert.ToInt32(n[0]);
koji.KojiName = n[1];
alKoji.Add(koji);
}

srList.Close();

}
else
{
FileStream sr = File.Create(FILEPATH_KOJILIST);
sr.Close();

}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}

この対処法をご存知の方いらっしゃいましたら、どうかよろしくお願いします。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2004-02-10 16:48
私のところでは以下のように保存されたテキストファイルをよみとって
TKojiの配列にちゃんと保存されましたよ。

1(タブ文字)名前1(改行)
2(タブ文字)名前2(改行)
 ・
 ・

ですが
>もし、入力にタブを使うとうまく保存できないです。
これどういう意味ですか?あと、このコードで何をしたいのか詳しく書かないと
わかりにくいです。できれば、何が問題なのかを示す最小のコードで。
(コードでなくてもいいです)

#Windowsアプリですよね、それとエンコード間違ってないですよね?
Beginner
会議室デビュー日: 2004/02/06
投稿数: 17
投稿日時: 2004-02-10 17:42
ご返信ありがとうございます。
詳細不足で申し訳ありません。
これはテキストがファイルにタブ区切りで保存してあるものを
ListBoxに表示するものです。

引用:

べるさんの書き込み (2004-02-10 16:48) より:

1(タブ文字)名前1(改行)
2(タブ文字)名前2(改行)
 ・



たとえば名前と1の間に入力する人が間隔を空けたくてタブを入力されたときに
このコードだと

1(タブ文字)名前(タブ文字)1(改行)
2(タブ文字)名前(タブ文字)2(改行)

while ((listName = srList.ReadLine()) != null)
{
string[] n = listName.Split(new char[]{'\t'});
koji.KojiID = Convert.ToInt32(n[0]);
koji.KojiName = n[1];
alKoji.Add(koji);
}

変数 n[0] = 1
n[1] = 名前
n[2] = 1
と保存されてしまいます。

これをタブが入力されたときでも
変数 n[0] = 1
n[1] = 名前(タブ文字)1
と保存されるようにしたいです。
このような事態にも対処するにはどうしたらよいでしょうか?

引用:

#Windowsアプリですよね、それとエンコード間違ってないですよね?



はい、windowsアプリです

よろしくお願いします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-10 18:01
 行として扱っていいんでしょうかねぇ?

 例えばCSVは、
・フィールドとフィールドの区切りはカンマである
・レコードの区切りは改行である
・フィールド中にカンマまたは改行を含む場合は、
 フィールド全体をダブルクォーテーションで囲む
・ダブルクォーテーションで囲まれたフィールドに
 ダブルクォーテーションを含むときは、ダブルクォーテーションを2つ続ける

となっています。
#もしかしたら、「これはカンマ(",")を含むフィールド」でも良かったかも
この「区切り」を「カンマ」から「タブコード」に換えれば、今回の事例に当てはまりますね。

 では、「タブコードを含むときはユーザにダブルクォーテーションで囲ませるのか」とか、「ダブルクォーテーションで囲った中にダブルクォーテーションを含むときは、2つ続けて入力させるのか」という問題があります。これが「できる」なら、そうすればいいし、できないなら、プログラム中で変換してやる必要があります。

 そうすると、ユーザ入力は「1行しかできない」のであれば、行単位に読み込んでいいのですが、そうでないならストリームを扱わなければなりません。ストリームとして扱って、

文字列フラグ = false
1文字読む
EOFか? はい: ループ終了
 いいえ:
  文字列フラグがfalseか?
   はい:
    入力文字は?
     ダブルクォーテーション:
      次の文字を読む
      ダブルクォーテーションか?
       はい: フィールドにダブルクォーテーションを追加
       いいえ:
        文字列フラグ反転
        1文字戻す
      ダブルクォーテーション判定終わり
     タブコード:
      フィールド確定処理
     リターンコード:
      レコード確定処理
     それら以外:
      フィールドに追加
    入力文字種別判定終わり
   いいえ:
    フィールドに追加
  文字フラグ判定終わり
EOF判定終わり

というような感じで読み込むしかないと思います。
ぢゃん♪
大ベテラン
会議室デビュー日: 2003/06/12
投稿数: 208
お住まい・勤務地: 都内
投稿日時: 2004-02-10 18:04
引用:

レコードさんの書き込み (2004-02-10 17:42) より:

変数 n[0] = 1
n[1] = 名前
n[2] = 1
と保存されてしまいます。

これをタブが入力されたときでも
変数 n[0] = 1
n[1] = 名前(タブ文字)1
と保存されるようにしたいです。
このような事態にも対処するにはどうしたらよいでしょうか?


それは、タブ区切りファイルの仕様にも関わります。
「区切りのタブ」と「入力文字のタブ」を区別する仕様を、ファイル仕様の中で決めていないと無理です。

考えられる方法は、ぱっと思いついたのでは

  1. "〜" で囲む
    (CSVファイルでは、こういう方法で「区切りのカンマ」と「文字のカンマ」を区別しています。)
  2. タブ文字を別の文字に置換する
    (たとえば「タブ」→「\t」、「\」→「\\」とか。C言語,C++,Java,C#のソースコードでよく使う方式ですね。)

といったところかな。

もちろん、1と2を同時にやるべき、という意味ではありません。

[ メッセージ編集済み 編集者: ぢゃん♪ 編集日時 2004-02-10 18:15 ]
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2004-02-10 18:34
引用:
1(タブ文字)名前(タブ文字)1(改行)
2(タブ文字)名前(タブ文字)2(改行)

変数 n[0] = 1
n[1] = 名前
n[2] = 1
と保存されてしまいます。

現実にタブ文字が存在するのでSplitメソッドを使えばそうなってしまいます。
では、コーディング以前に、どういうアルゴリズムで区切りたいかです。例えば
「1行の中で、1個目のタブ文字の前と後ろで2つに区切る」でよいならば、
IndexOfメソッドとSubstringメソッドで割りと楽にできそうです。ですが
入力に改行を許可する場合ですと、Jittaさんのおっしゃってる事情があります。
入力時に文字列をある程度操作したほうがよいかもしれませんね。
Beginner
会議室デビュー日: 2004/02/06
投稿数: 17
投稿日時: 2004-02-11 00:23
皆様ご回答ありがとうございます

ご意見を参考に少しいろいろ試してみたいと思います。

ありがとうございました

スキルアップ/キャリアアップ(JOB@IT)