数値文字列を整数に変換するには?

解決


MenPin  2010-05-20 22:02:31  No: 71635  IP: [192.*.*.*]

winsockで受信したデータを文字型から整数に変換したいのですが、
例えば、ReadBuff[12] の内容が "123456789010"だとすると、
win32API関数のlstrcpynで切り取る所までは分かるのですが、
str1[4] = "123"
str2[9] = "45678901"
これを整数型に変換する関数はありますか?
ゆくゆくはCreateThreadを使うかもしれないので、
できればwin32API関数がいいです。
よろしくお願いします。m(_ _)m

編集 削除
MenPin  2010-05-20 22:03:56  No: 71636  IP: [192.*.*.*]

訂正)例えば、ReadBuff[12] の内容が "12345678901"だとすると、

編集 削除
Yossi  2010-05-20 23:00:51  No: 71637  IP: [192.*.*.*]

atoi() atol() ではダメなんですか?

編集 削除
MenPin  2010-05-20 23:23:13  No: 71638  IP: [192.*.*.*]

おお、そんな関数があったんですね。
使ってみます。ありがとうございました。

編集 削除
tetrapod  2010-05-21 06:29:34  No: 71639  IP: [192.*.*.*]

ネットワーク電文として整数値をASCIIに変換したものを送ろうとしている?
無駄なのでやめよう。
ネットワークバイナリを使うほうがいいぞ。
hton 系関数でホスト→ネットにエンディアン変換し、
ntoh 系関数でネット→ホストにエンディアン変換するといい。

編集 削除
MenPin  2010-05-21 12:47:35  No: 71640  IP: [192.*.*.*]

>  無駄なのでやめよう。
10進数で送るより16進数で送るほうがバイト数が減るからでしょうか?

>  にエンディアン変換
例えば send で送るデータ 0x000102 を格納している sendBuff[3] が、
sendBuff[0] -> 0x00 sendBuff[1] -> 0x01 sendBuff[2] -> 0x02
だったとすると
recv で受信した recvBuff[3] の内容は、
recvBuff[0] -> 0x00 recvBuff[1] -> 0x01 recvBuff[2] -> 0x02
ではなく
recvBuff[0] -> 0x02 recvBuff[1] -> 0x01 recvBuff[2] -> 0x00
になるのでこれを変換するという事でしょうか?

まだ見ていらしたら、よろしくお願いします。m(_ _)m

編集 削除
aetos  2010-05-21 13:48:49  No: 71641  IP: [192.*.*.*]

> 10進数で送るより16進数で送るほうがバイト数が減るからでしょうか?

文字列で送るより数値で送る方がバイト数が減るからです。

 "100" は3バイトですが 100 は1バイトで送れます。

編集 削除
tetrapod  2010-05-21 14:08:23  No: 71642  IP: [192.*.*.*]

> 10進数で送るより16進数で送るほうがバイト数が減るからでしょうか?
表記がヘンというか語彙が正しくないというか?
バイナリ表記で送るほうがバイト数が減るから。

現時点(2010年当時)で、およそ一番コスト高(遅いと言い換えてもよい)なのは通信であり、
通信コストに比べればCPUの演算速度や記憶装置の容量は無視できるくらい安価と言っていい。

なので、通信データのバイト数は1オクテットでも少ないほうがよい。
特定目的専用の通信なら、電文が最短になるバイナリ表記が一番よい。

提示例は 24bit 値を送受信するということだと解釈させていただく。
符号なし 24bit 値は [0..16777215] であるため
・バイナリ表記 = 3octet
・ASCII による10進表記 = 8octet(要デリミタなら+1)
・ASCII による16進表記 = 6octet(要デリミタなら+1)
が必要になるというあたりの理解は大丈夫なのだろうか?

ネットワークバイトオーダーの話は上記が理解できていて何ぼなので今は略。

編集 削除
MenPin  2010-05-21 16:00:46  No: 71643  IP: [192.*.*.*]

> が必要になるというあたりの理解は大丈夫なのだろうか?
はい理解できています。

しかし、sendで送ったバッファがrecvで受け取るとき順番が変っているのでしょうか?
どの部分でネットワークバイトオーダーを意識する必要があるのでしょうか?

まだ見ていらしたら、よろしくお願いします。m(_ _)m

編集 削除
tetrapod  2010-05-21 16:30:14  No: 71644  IP: [192.*.*.*]

そこまでわかっているなら [ネットワークバイトオーダー] について調べてみりゃいい。
よい解説がいっぱい転がっているはずだ。

編集 削除
MenPin  2010-05-21 17:25:43  No: 71645  IP: [192.*.*.*]

ネットワークバイトオーダーを意識しなくてはならないのは、sendやrecvで送受信する時ではなく、
送信数値データを送信バッファのchar配列に格納する時や、
受信バッファのchar配列から数値データとして取り出す時に、
意識しなくてはならないという風にサイト見てて解釈しました。

PC→ネット→相手PC  と考えたときに、相手PCがリトルエンディアンで数値データを扱っているのか、ビッグエンディアンで扱っているのかが不明(相手PCが決まっていない場合)、ネット上にはとりあえずビッグエンディアンでデータを流しますから、受け取り側のPCでそのPCにあったエンディアンに個別に変換して対応してください。という事みたいです。

私の場合は、サーバーもクライアントもwindowsマシンと分かっているので、変換する必要はないのですが、一応送受信データはビッグエンディアンで送ろうと思います。

htonlは4バイト、htonsは2バイトみたいですが、3バイト1バイトなどの場合は自分で変換する必要があるみたいですね。

終了後までお付き合い頂きありがとうございました。m(_ _)m

編集 削除
仲澤@失業者  2010-05-21 17:56:13  No: 71646  IP: [192.*.*.*]

>htonlは4バイト、htonsは2バイトみたいですが、3バイト1バイトなどの場合は自分で変換する必要があるみたいですね。

C/C++言語には3Byteの型は無いので4Byteのlongで扱うのが普通です。
もちろん、変換後に3Byteだけを送付するのはありですが、まぁ
一般的にはやりません(vv;)。
1Byteは「Byte並び(エンディアン)」という概念は無意味なので、
考慮する必要はありませんね(^^)。

編集 削除
MenPin  2010-05-21 18:23:22  No: 71647  IP: [192.*.*.*]

なるほどです。回答ありがとうございます。
なるべく送信サイズを減らすという意味では3バイトもありかもと思っていましたが、面倒ですよね、4バイトで送ったほうが美しいかも^^

編集 削除