3
DWORD disk_serialINT[MAX_PATH + 1];
GetVolumeInformationA(NULL, NULL, NULL, disk_serialINT, NULL, NULL, NULL, NULL);
char* disk_serialANSI;
sprintf(disk_serialANSI, "%d", disk_serialINT);
std::string HDDserial = disk_serialANSI;

これは、hdd シリアル番号を取得するコードですが、問題は、プログラムを実行するたびに値が異なることです。誰かがそれを説明できますか?

解決済み:

DWORD disk_serialINT;
GetVolumeInformationA(NULL, NULL, NULL, &disk_serialINT, NULL, NULL, NULL, NULL);
std::string HDDserial = std::to_string(disk_serialINT);

ありがとう。

4

3 に答える 3

8

これらの 2 行により、未定義の動作が発生します。

char* disk_serialANSI;
sprintf(disk_serialANSI, "%d", disk_serialINT);

ポインター変数を宣言しますが、実際にはどこにもポイントしません。初期化されていないローカル変数には不確定な値があり (実際にはランダムに見える)、その初期化されていないポインターを使用すると、呼び出しがどこに書き込まれるかわかりません。sprintf


C++ でプログラミングしているため、解決策がいくつかあります。

  • 昔ながらの方法はdisk_serialANSI、数値を保持するのに十分な大きさの文字の配列を作成することです (文字列ターミネータを含む)。別の方法として、ポインターに手動でメモリを割り当て、使い終わったらそのメモリを再度解放することもできます。

  • を使用std::ostringstreamしてデータをフォーマットし、std::string.

  • std::to_string文字列に直接変換するために使用します。

  • Boost Lexical castを使用します。

于 2015-01-28T13:41:04.437 に答える
2

Joachim の言うことに加えて、シリアル番号を正しく渡していません。単一の値へのポインターを渡す必要があります。

DWORD disk_serialINT;
GetVolumeInformationA(NULL, NULL, NULL, &disk_serialINT, NULL, NULL, NULL, NULL);

あなたのコードでは、これはあなたがここで行うことによって複雑になります:

sprintf(disk_serialANSI, "%d", disk_serialINT);

Joachimの回答がカバーする uninitialized variable を無視すると、フォーマット文字列disk_serialANSIへのポインタを渡しています。単一の値に"%d"変更すると、状況が改善されます。disk_serialINTただし、符号なしの値を単一のフォーマット文字列に渡しています。

これらの厄介な C 書式設定関数をあきらめて、C++ 標準ライブラリを使用して整数値とテキストを変換するときが来ました。

最後に強調すべき点は、Win32 API への呼び出しの戻り値を確認する必要があることです。関数呼び出しが成功したかどうかはわかりません。そうだと思い込んではいけません。これはすべてドキュメントで説明されています: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993.aspx

このプログラムは、現在のディレクトリを含むボリュームのシリアル番号を出力します。

#include <Windows.h>
#include <iostream>

int main()
{
    DWORD disk_serialINT;
    if (!GetVolumeInformationA(NULL, NULL, NULL, &disk_serialINT, NULL,
        NULL, NULL, NULL))
    {
        std::cout << "Failed: " << GetLastError() << std::endl;
        return 1;
    }
    std::cout << "Current directory volume serial numnber: " << std::hex 
        << disk_serialINT << std::endl;

    return 0;
}
于 2015-01-28T13:41:41.903 に答える