3

ASCII 文字列を単一の浮動小数点数に変換する助けが必要です。私のデータの形式は次のとおりです。

ÀV3é¾V3»V3AÀV3ÁV3Û¶V3ÅV3=¾V3âºV3ðÂV3߸V3¿

4 文字ごとに浮動小数点数を表す必要があります。例: 50.90101e-9;

次の C++ コードを使用して、この文字列を読み取り可能なデータに変換しようとしています

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>


int main (void)
{
    int i;
    int no_of_bytes;
    char temp_string[2048];
    float this_reading[100];
    char *ptr;
    no_of_bytes=32;

    sprintf(temp_string,"%i",no_of_bytes*4);

    /*convert char string to floating point*/
    sprintf(temp_string,"%i","ìÀV3é¾V3»V3AÀV3ÁV3Û¶V3ÅV3=¾V3âºV3ðÂV3߸V3¿V3é¾V3ÁV3Û¶V3é¾V3ìÀV3ÁV3é¾V3ÁV3=¾V3DÂV3DÂV30¶V¿V3:¼V3¿V3ìÀV3,´V3¿V3·V3ìÀV3");
    ptr=&temp_string [1];
    /*convert char string to floating point*/
    for(i=0; i<no_of_bytes; i++)
    {
        //puts(ptr);
        this_reading [i] = *((float*)ptr);
        ptr = ptr+4;
        printf ("%e \n", this_reading [i]);
    }
}
/*end of main*/

しかし、次の結果が得られます。

6.665629e-10 
-6.321715e-30 
4.056162e-02 
-5.629500e+14 
1.259217e-18 
1.779649e-43 
3.087247e+23 
2.350968e-38 
-2.437012e+01 
9.439035e-38 
0.000000e+00 
-2.000000e+00 
-nan 
1.661560e+35 
4.056162e-02 
-5.629500e+14 
1.259217e-18 
1.779649e-43 
3.096102e+23 
2.350968e-38 
-2.437012e+01 
1.628646e+32 
0.000000e+00 
6.490371e+32 
0.000000e+00 
0.000000e+00 
2.596148e+33 
0.000000e+00 
1.038459e+34 
4.153837e+34 
0.000000e+00 
0.000000e+00

同じメソッドを使用して、変換しようとしている値に近い浮動小数点数を取得して、それを文字に変換し、浮動小数点数に戻そうとしましたが、結果にも同じエラーが発生します。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>

int main (void)
{

    float reading;
    float number;
    char *ptr;
    float *pointer_number;
    char temp_char ;

    number = 50.90101e-9;
   pointer_number = & number;

    printf ("%e \n",*pointer_number);
    temp_char  = *((char*)pointer_number);

    printf ("%c \n",temp_char);

   ptr=&temp_char ;
    puts(ptr);

    reading  = *((float*)ptr);
    printf ("%f \n", reading);

}
/*end of main*/

.

5.090101e-08 
A 
AA�Z3
22272396874481664.000000 

私は C/C++ データ宣言と操作の専門家ではありません。私の最終的な目的は、Matlab でこの変換を行うことです。私は非常に古い楽器からこの値を読み取っています。彼らは、計測器のマニュアルで、浮動小数点演算の IEEE 標準 (ANSI/IEEE Std. 754-1985) を使用してクエリ データが 2 つのサイズのデータ​​型をサポートすることを指定しています。

ありがとうございました!

4

2 に答える 2

2

あなたの問題は、temp_stringゴミが含まれていることです。

sprintf(temp_string,"%i", string_literal)

間違っている。 %iは文字ポインターと互換性がありませんsprintfが、可変引数関数であるため、コンパイラーは型の不一致を認識しません。

を失い、sprintfただ試してみてください

const char* ptr = "...";

その後、ループが機能するはずです。

またはさらに簡単です:

const float *this_reading = (float*)"...";

配列と同じように使用します。

もちろん、このコードはすべて、データのバイト順が C++ プラットフォームに一致することを前提としています。しかし、数値処理にもっと興味がある場合は、「十分に機能する」はずです。

于 2013-06-10T14:26:21.803 に答える
1

最初の 10 個の値は

0 5.000122e-08
1 4.999939e-08
2 ?
3 5.000061e-08
4 ?
5 4.999206e-08
6 4.985647e-08
7 4.999878e-08
8 4.999573e-08
9 5.000305e-08
...

私の 4 バイト リトルエンディアン floatコンピューターに50.90101e-9変換した例。これはこれまでの 3 番目、4 番目の文字 (ほぼ) に似ているため、文字列が同じリトル エンディアンの float 形式であることを示唆しています。文字列を C ファイルに入れるには 2 つの問題があります。私のCファイルでは、「ìÀV3é¾ ...」文字列をUTF8エンコーディングに変換しました。それをフロートと統合することで、混乱が生じました。提示された文字列には、確かにいくつかのバイトが欠けています。(float #2 を通過するためにいくつか追加しました。) 真の文字列はファイル内の元の形式で利用できると仮定します。ファイルをバイナリで開き、そのファイルを一度に 4 バイトずつ読み取ります。A � Z 3CZ 3float

FILE *inf = fopen("Stringfilename", "rb");
int i = 0;
float f;
while (fread(&f, sizeof(f), 1, inf) == 1) {
  printf("%d %e\n", i++, f);
}
fclose(inf);
printf("%d floats read.\n", i);
于 2013-06-10T16:44:51.887 に答える