2013年9月6日金曜日

文字列を数値に変換する関数とその使い方

実行風景



以下コード=====================================================
#include <tchar.h>
#include <string>
#include <math.h>//pow関数に必要

//プロトタイプ宣言
int CharacterToValue(std::string Character,int Forward,int Backward);//文字列の指定した範囲を数値に変換してreturnする関数

int main(void){
 std::string SCI_pBufferRecieved;//受信した文字のバッファ
 SCI_pBufferRecieved=_T("0123456789");
 //格納されている文字列を数値に変換して格納する。
 int AD_Result0 = CharacterToValue(SCI_pBufferRecieved,0,0);
 int AD_Result1 = CharacterToValue(SCI_pBufferRecieved,1,1);
 int AD_Result2 = CharacterToValue(SCI_pBufferRecieved,9,9);
 int AD_Result3 = CharacterToValue(SCI_pBufferRecieved,0,9);
 int AD_Result4 = CharacterToValue(SCI_pBufferRecieved,1,5);//前から、0から数え始めて1番目と5番目までの文字を数値に変換
 int AD_Result5 = CharacterToValue(SCI_pBufferRecieved,3,6);
 int AD_Result6 = CharacterToValue(SCI_pBufferRecieved,4,9);
 int AD_Result7 = CharacterToValue(SCI_pBufferRecieved,0,8);

 printf("%d\n",AD_Result0);
 printf("%d\n",AD_Result1);
 printf("%d\n",AD_Result2);
 printf("%d\n",AD_Result3);
 printf("%d\n",AD_Result4);
 printf("%d\n",AD_Result5);
 printf("%d\n",AD_Result6);
 printf("%d\n",AD_Result7);
 printf("\n\n\n");
 SCI_pBufferRecieved=_T("00120");
 int AD_Result10 = CharacterToValue(SCI_pBufferRecieved,0,4);
 printf("%d\n",AD_Result10);
 system("pause");
 //system("pause > NUL");
 return 0;
}





//指定された範囲の文字列を数値に変換する関数(ゼロ以上の整数限定)

int CharacterToValue(std::string Character,int Forward,int Backward){

//Forward:「前方の」から数えてForward番目の文字,Backward:(「前方の」から数えて)「後方の」Backward番目の文字
 int Value=0;

 for(int Number=Forward
, Power=(Backward-Forward);       //これで両方ともintとして宣言されているはず。(異なる型の場合、このような宣言は不可。その場合は外で宣言する)
  (Number<=Backward);
//(Number<=Backward)&&(Power>=(Backward-Forward)); //タイミングとしては同じになるハズなのでどちらか一方でOK
  Number++, Power-- )//ここまでfor文
 {
  //Number:「数」の意味//[2]~[9]
  //Power:「乗」の意味//10^7~10^0
  Value += (Character[Number]-'0')*(int)pow((double)10,(double)Power);
  //(SCI_pBufferRecieved[Number]-'0')でアスキーコード(文字コード)を数値に変換する。(何故こうなるのかはアスキーコード表を参照すれば分かるはず)
 }

 return Value;
}
//==================================================================

 //実例に即して考えてみる
 //
 //■■□□□□□□□□■■
 //[0]~[11]までの12文字
 //□は8文字
 //変数がそれぞれ次のように定義される時
 //Forward=2  //ゼロから数え始めている事に注意!!
 //Backward=9 //ゼロから数え始めている事に注意!!
 //Backward-Forward=9-2=7
 //□を数値に変換する場合
 //
 //Value=[2]*(10の(Backward-Forward)乗)
 //  +[3]*(10の(Backward-Forward-1)乗)
 //  +[4]*(10の(Backward-Forward-2)乗)
 //  +[5]*(10の(Backward-Forward-3)乗)
 //  +[6]*(10の(Backward-Forward-4)乗)
 //  +[7]*(10の(Backward-Forward-5)乗)
 //  +[8]*(10の(Backward-Forward-6)乗)
 //  +[9]*(10の(Backward-Forward-7)乗)←+[9]*(10の(0)乗)
 //注意事項
 //1.文字列は0番目から数え始めている。
 //2.Forward<Backwardが成り立つ必要がある。
 //3.半角数字以外を指定してはいけない
 //4.変換できるのは0以上の整数だけ

Win32APIによるシリアル通信・その①

  Top  > Win32APIによるシリアル通信 > Windows API によるシリアル通信(RS232C)

特徴:
受信処理を別スレッドで実行している事……くらいです。
(要するに非同期通信なので、受信待機中に他の処理を行う事ができます。)

実験方法:
USB⇔シリアル・変換ケーブルの2番ピンと3番ピンをワニ口クリップでショートさせて、送信したデータを受信する。

環境:
Win7 x64 Visual C++ 2012

「新しいプロジェクト」⇒「空のプロジェクト」
でプロジェクトを作って
「プロジェクト(P)」⇒「新しい項目の追加(W)」⇒「C++ファイル(.cpp)」
で作ったファイルにそのままコピーしてビルドすればたぶん動きます。(環境が同じなら……)

ポート番号"COM7"の部分はデバイスマネージャーから確認して適切な値にセットしてください。USBポートの挿す位置が変わるだけで番号が変わっていくので注意してください。


実行風景


上の行のアンダーバー以降が送信した文字列
下の行が受信した文字列になります。


一応これだけで、非同期シリアル通信が可能ですが、
現実的にはこのコードだと多少問題があります。
例えば、現在終了コードを「\0」としていますが、これを「\r\n」とする事でハイパーターミナルを
返した通信と同じ状況になる(ハズ)ですが、このままだと、
下記のようなデータを送信した場合、
「"□□□□□\r\n△△△△△\r\n\0\0\0……"」
受信したデータが、
「"□□□□□\r\n△△\0\0\0……"」「"△△△\r\n\0\0\0……"」のようにデータが二つの
バッファに分かれてしまう場合があるので、きちんと処理しないとバグを
引き起こします。

この辺りの解決策はWin32APIによるシリアル通信。続き。を参照してください。


以下ソースコードです。

余りにも見難いのでサンプルを置いておきます。
http://ux.getuploader.com/ADMIS/download/8/Serial_Communication_Interface_Ver0.7.zip



  Top   > Win32APIによるシリアル通信 > Windows API によるシリアル通信(RS232C)

2013年9月4日水曜日

std::stringをlength()で文字列の長さを格納しようとしたとき、何故か文字列は入っているのに長さに0が返される。おかしいと思ってデバッカで追ってみると、std::stringの長さを格納している_Mysizeが0のままである事に気が付いた。おそらく何か(自分のコードに)ミスがあるためだろうとは思うが、取りあえず、

std::string buff;
buff._Mysize=文字数;

と(手動で代入)する事で、length()から文字数が返るようになった。


丁度RS232Cのプログラムを書いていた所だったのだが、以下の行で_Mysizeが正しくセットされていなかった。何がいけなかったのだろうか……。.c_str()の処理で情報量が減ってるとか?
ReadFile(hComPort, (LPVOID*)SCI_pBufferRecieved.c_str(), lengthOfRecieved, &SCI_LengthOfPutOrRecieved, NULL);

2013年9月3日火曜日

3つのstringの違い

CString                  MFC(≒Visual C++)
System::String      .NET Framework
std::string             標準C++言語仕様の一部