質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

Q&A

解決済

2回答

4020閲覧

PadLeftコマンドについて教えてください。

fender0131

総合スコア121

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

0グッド

0クリップ

投稿2015/11/10 06:53

編集2015/11/10 08:22

いつも大変お世話になっております。

PadLeftについて質問させて頂いてもよろしいでしょうか。

using (BinaryWriter w = new BinaryWriter(File.OpenWrite(@"c:\data\test.dat")))
{
foreach (data Item in lst)
{
w.Write(Item.combobox1.PadLeft(15, '\0'));
・・・

}

上記のプログラムソースでdatファイルにコンボボックスやテキストボックスに書き込まれた文字や値を書き込んでいました。

アルファベットや数字の際は、「0」のパディングが入り書き込むことができたのですが、
日本語の場合、「0」のパディングが上手く入らず、データにずれが生じてしまいました。

「 w.Write(Item.combobox1.PadLeft(15, '\0'))」は、日本語では使用できないのでしょうか?

お手数おかけして申し訳ございませんが、ご指導ご鞭撻の程よろしくお願い致します。

以下がその例となります。

・ w.Write(Item.combobox1.PadLeft(15, '\0'))を使用。
・ 書き込む文字が「テスト」

すると以下のような結果となります。

イメージ説明

=================================================

●追記2

kutsulogさんのお答えを元にプログラムを書き換えてみました。

Encoding enc = Encoding.GetEncoding("Shift_JIS");

foreach (data Item in lst) { w.Write(Item.joint_cb.PadLeft(15 - (enc.GetByteCount(Item.joint_cb) - Item.joint_cb.Length),'\0')); }

としたところ、3バイト短くなりましたが、以前15バイトに納められずにいます・・・

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

文字列をファイルで読み書きする際は、エンコーディング(簡単に言えば文字コードの違い)を意識しないと思わぬ問題を引き起こします。

C#は内部的には文字列をUTF-16で扱い、英数字のようなASCII文字と多くの日本語文字は16bitで表現されます。PadLeftに渡した'\0'も内部では16bitで保持されています。ところが、ファイルに書き出すときにUTF-8に変換されて、ASCII文字は1バイト、日本語文字は3バイトと異なるサイズになってしまっています。

固定長であることが重要なのであれば、ファイルにはUTF-16のまま書き込めば良いでしょう。BinaryWriterをnewするところで第二引数にEncoding.Unicodeを渡せば良いと思います。
16バイトであることが重要ならば、扱う文字数は8文字に制限されてしまいます。
もし、UTF-8で書きたいのであれば、16バイトだと日本語は5文字しか入らないかもしれません。
このように、文字列をファイルで扱うのは時に面倒なのです。

ちなみに、厳密にはUTF-16の1文字は最大32bitなので、それを考慮するとなると固定サイズで扱うにはUTF-32を使うことになるかもしれません。文字列をちゃんと扱おうとすると結構面倒です。

投稿2015/11/10 08:46

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fender0131

2015/11/10 09:17

お答えありがとうございます。 エンコーディングの知識が足りませんでした。 今回の件で、エンコーディングの重要性を確認することができました。 また、分かりやすく解説して頂きありがとうございました。 大変わかりやすかったです。 誠に申し訳ないのですが、ベストアンサーは先にお答えいただいた方につけさせて頂きました。本当でしたらお二人につけさせて頂きたいのですが。。。
catsforepaw

2015/11/10 09:22

いえいえ、お気になさらず。これが唯一の正しいやり方というものはないので、状況や目的に応じて時には試行錯誤しながら私もやっております。
guest

0

ベストアンサー

PadLeftは指定の文字数になるまで指定文字で埋める処理なので
定義通りの処理になっています。
(英数字でできていたのは文字数=バイト数だから)

バイト数でやりたかったら
Item.combobox1.PadLeft(15-(Encoding.Default.GetBytes(Item.combobox1) - Item.combobox1.length), '\0')
など調節すればよいはずです

投稿2015/11/10 07:09

kutsulog

総合スコア985

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fender0131

2015/11/10 08:27

お答えありがとうございます。 w.Write(Item.joint_cb.PadLeft(15 - (Encoding.Default.GetBytes(Item.joint_cb) - Item.joint_cb.Length), '\0')); と書き換えてみたのですが、 error CS0019: 演算子 '-' を 'byte[]' と 'int' 型のオペランドに適用することはできません。 というエラーが出てしまいました。 エラーを回避しようとした結果、追記2のようなプログラムになりました。 しかし、こちらも思い通りの結果が出ずにいます。 お手数おかけして申し訳ございませんが、再度ご教授願えませんでしょうか?
kutsulog

2015/11/10 08:58 編集

サンプルなのでSJISのDefaultにしましたが、 バイナリをみると日本語が3バイトになっているので エンコードの種類はUnicodeでバイト数をカウントすれば 希望の処理になると思います
fender0131

2015/11/10 09:13

お答えありがとうございます。 思い通りの結果を出力することができました。 エンコーディングを全く意識していなかったことが原因でした。 しっかり理解し、今後のプログラムに活かせるよう努力したいと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問