xinbc1314 2016-06-28 11:58 采纳率: 0%
浏览 840

初学C语言,折腾了好久,请大大们指导下。结贴

刚申请账号,原来都是看各位老师回答,是不是刚申请的没有积分或者C币奖赏

希望老师们能指点一二 谢谢
程序用途 HDDのSMART情報が格納されたバイナリファイル(HDD_SMART_INFO.dat)をキャラクタに変換後、csvファイルとして出力する CSVをもとにデータを解析し、故障しそうなHDDを事前に見つける際に使用するツール。
程序功能
cmd命令 下输入

不指定功能情况下
.*dat test.csv 当前路径全dat文件 读取 test.csv输出
test.dat test.csv 单一dat文件指定 读取 test.csv输出
功能指定情况下
-OR .*dat test.csv 当前路径全dat文件 读取 按功能指定 test.csv输出
-OR test.dat test.csv 单一dat文件指定 读取 按功能指定test.csv输出

根据当前路径 检索路径下所有.dat文件 包括路径下文件夹内存在.dat文件的情况下检索到底 到没有文件夹位为止获取所有dat文件

.dat文件用专门软件打开后内容大体为
01 0B 00 64 64 10 00 00 00 00 00 00
02 05 00 88 88 36 5E 00 00 00 00 00
.
.
.
以第一行为例
01 为 AttributeID uchar 1字节
0B 00 为AttributeFlag ushort 2字节
64 为CurrentValue uchar 1字节
64 为WorstValue uchar 1字节
10 为ThresholdValue uchar 1字节
00 00 00 00 00 00 为RawValue uchar[6] 6字节

三种功能设定
-OR Raw数据输出
-OV Value数据输出
-RC Raw数据反序输出

再次谢谢

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  SMART変換ツール :
// HDDのSMART情報が格納されたバイナリファイル(HDD_SMART_INFO.dat)を                                     
// キャラクタに変換後、csvファイルとして出力する                                     
// CSVをもとにデータを解析し、故障しそうなHDDを事前に見つける際に使用するツール                                        
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <stdafx.h>
#include<stdio.h>   
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
#include<malloc.h>

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//オプション                                   
//  デフォルトでは                                   
//   -OR:Rawデータだけ出力                                   
//        -OV:Valueだけ出力                                   
//    -RC:Rawデータを以下のように並び替えて出力                                  
//          0123456789AB        ⇒ AB8967452301
/***オプションの設定***/
#define S_OR "-OR"                  
#define S_OV "-OV"
#define S_RC "-RC"

#define OUTPUT_ORDATA   1
#define OUTPUT_OVDATA   2
#define OUTPUT_RCDATA   3
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/***SMARTデータ最大数***/
#define SMART_DATA_MAX  64

#define NORMAL_END      0
#define ABNORMAL_END    1

/***構造体の定義***/
struct SMART_INFO       
{
    unsigned char   AttributeID;
    unsigned short  AttributeFlag;
    unsigned char   CurrentValue;
    unsigned char   WorstValue;
    unsigned char   ThresholdValue;
    unsigned char   RawValue[6];
};

struct SMART_ALL_DATA
{
    SMART_INFO stSmartInfo[SMART_DATA_MAX];
    char FileNames[_MAX_PATH];
};


/***関数宣言***/
int GetParamData( int argc,_TCHAR* argv[],char *cpOutFileName, char *cpFileName,char *cpSearchPath ,int *iOption ); 
int FileSearch( int *iCount , char*cpSearchPath, SMART_ALL_DATA *stSmartAllInfo);
int File_r( char *cpSearchPath, SMART_ALL_DATA *stSmartAllInfo, int iFileNo );
int FileOut( char *cpOutFileName, SMART_ALL_DATA *stSmartInfo,int iCount, int iOption );

////////////////////////////////////////////////////////////////////////////////////////////////////////
// 関数名:main
// 機能  :メイン処理
// 引数  :argc   : 引数の個数
//        argv[] : 引数の値(.datファイル名と.csvファイル名を取得用)
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
int _tmain( int argc,_TCHAR* argv[] )
{   
    //.datファイル複数の場合、検索パス用
    char Search_Path[_MAX_PATH]={0};                            

    //.datファイルをオープンの場合、フルパス+.datファイル名用
    char Filename[_MAX_PATH]={0};                               

    //出力csvファイル名を格納用
    char cOutFileName[_MAX_PATH]={0};                           
    //オプション格納用
    int iOption=0;                                              

    //.datファイル個数を記録用
    int iCount=0;                                               

    //構造体を宣言
    SMART_ALL_DATA *stSmartAllData = NULL;

    //関数の真偽判断
    int iResult = FALSE;

    //引数の判断   
    if(argc<3)
    {                                                           
        printf( "Input Error.\n" );
        printf( "Please input some words such as \"-Option FileName.dat FileName.csv\".\n" );
        return ABNORMAL_END;
    }

    //引数解析
    iResult = GetParamData( argc, argv, cOutFileName, Filename,Search_Path, &iOption ); 
    if( iResult!= 0 )
    {
        //単一ファイル指定用
        char *cpFileDat = ".dat";

        //複数ファイル指定用
        char *cp_AllDat = "*.dat";

        //if( 引数のパスに'*'があるか? )
        if ( strstr( Filename,cp_AllDat ) != NULL)
        {   // '*'がある場合

            // ファイル検索(個数を取得処理)    
            FileSearch( &iCount,Search_Path ,NULL );  

            if (iCount == 0 )
            {
                printf("Can not search any DatFiles.\n");
                return ABNORMAL_END;
            }

            // 構造体を定義
            stSmartAllData = ( SMART_ALL_DATA* )malloc( iCount * sizeof(SMART_ALL_DATA) );

            //メモリ確保
            if( stSmartAllData == NULL )
            {
                printf( "Memory allocation failed.\n" );
                return ABNORMAL_END;
            }

            //初期化
            memset( stSmartAllData, '\0' , ( iCount * sizeof(SMART_ALL_DATA ) ) );

            // ファイル検索処理(リード処理を行う)   
            iCount = 0;

            iResult = FileSearch( &iCount, Search_Path ,stSmartAllData );  
        }
        else
        {   
            if ( strstr( Filename,cpFileDat ) != NULL)
            {
                // '*'がない場合
                // ファイル個数は1個
                iCount = 1;

                // 構造体を定義
                stSmartAllData = ( SMART_ALL_DATA* )malloc( iCount * sizeof( SMART_ALL_DATA ) );

                //メモリ確保
                if( stSmartAllData == NULL )
                {
                    printf( "Memory application failed.\n" );
                    return ABNORMAL_END;
                }

                //初期化
                memset( stSmartAllData, '\0' , ( iCount * sizeof(SMART_ALL_DATA ) ) );

                iCount = 0;
                //リード処理を実行      
                iResult = File_r( Filename, stSmartAllData, iCount++ );

                //ファイルオープン失敗の場合 ファイル名を出力
                if( iResult == FALSE )
                {   
                    printf( "Can not to open %s.\n" ,Filename);
                    printf( "Please make sure the FileName and FullPath.\n");
                }
            }
            //DATファイルではない場合
            else
            {
                printf("Input Error.\n");
                printf( "Please input some words such as \"-Option FileName.dat FileName.csv\".\n" );
                return ABNORMAL_END;
            }
        }

        if( iResult== TRUE )
        {
            //csvファイルを出力
            FileOut( cOutFileName, stSmartAllData, iCount, iOption );    
        }

        //mallocを解放する。
        free(stSmartAllData);
    }

    return NORMAL_END;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// 関数名 : GetParamData
// 機能 : 引数の解析処理
// 引数 : argc            : 引数の個数
//        argv[]        : 引数の値(.datファイル名と.csvファイル名を取得用)
//       cpOutFileName : csvファイル名             
//        cpFileName    : .datファイルをオープンの場合、フルパス+.datファイル名用
//        cpSearchPath  : .datファイル複数の場合、検索パス用
//       iOption      : オプション格納用
////////////////////////////////////////////////////////////////////////////////////////////////////////
int GetParamData( int argc,_TCHAR* argv[], char *cpOutFileName,char *cpFileName, char*cpSearchPath ,int *iOption )
{   //戻り値設定
    int iResult = FALSE;

    //argv[Dat_Name]格納 && argv[Csv_Name]格納
    int Dat_Name,Csv_Name;

    Dat_Name=(argc==3?1:2); 
    Csv_Name=(argc==3?2:3);

    //取得の引数によって、オプションの判断
    if(strcmp( argv[1], S_OR ) == 0)
    {
        //"-OR"を取得する場合
        *iOption = OUTPUT_ORDATA;
    }
    else if(strcmp( argv[1], S_OV ) == 0)
    {
        //"-OV"を取得する場合
        *iOption = OUTPUT_OVDATA;
    }
    else if(strcmp( argv[1], S_RC ) == 0)
    {
        //"-RC"を取得する場合
        *iOption = OUTPUT_RCDATA;           
    }

    //パス分解する用
    char szPath[_MAX_PATH];
    char szDrive[_MAX_DRIVE];
    char szDir[_MAX_DIR];
    char szFileName[_MAX_FNAME];
    char szExt[_MAX_EXT];
    DWORD dwRet;

    //初期化
    memset( szPath, NULL, sizeof( szPath ) );
    memset( szDrive, NULL, sizeof(szDrive ) );
    memset( szDir, NULL, sizeof( szDir ) );
    memset( szExt, NULL, sizeof( szExt ) );
    dwRet = 0;

    //実行中のプロセスフルパスを取得する。
    dwRet = GetModuleFileName(NULL, szPath, sizeof( szPath  ) );

    //エラー処理
    if( dwRet == 0 ) 
    {   
        int Errorcode;
        Errorcode=GetLastError();
        printf("Error code %d :Get CurrentDirecory Error.\n",Errorcode);
        return iResult;
    }

    //フルパス名を分割する
    _splitpath_s( szPath, szDrive, szDir, szFileName, szExt );          

    //.csvファイいるを取得し、cpOutFileNameに格納
    memset( cpOutFileName, NULL, _MAX_PATH );   
    strcpy_s( cpOutFileName, _MAX_PATH, argv[Csv_Name] );

    //検索パスを取得処理     
    strcat_s( cpSearchPath, _MAX_PATH, szDrive );
    strcat_s( cpSearchPath, _MAX_PATH, szDir ); 

    //.datファイルをオープンの場合、フルパス+.datファイル名用を取得処理
    strcat_s( cpFileName, _MAX_PATH, szDrive );
    strcat_s( cpFileName, _MAX_PATH, szDir );   
    strcat_s( cpFileName, _MAX_PATH, argv[Dat_Name] );

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// 関数名 : FileSearch
// 機能 : .datファイル複数の場合、検索処理
// 引数 : iCount      : ファイル個数記録用
//        cpSearchPath  : 検索パス
//
//       stSmartAllInfo : リードするデータを保存用          
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
int FileSearch( int *iCount,char *cpSearchPath,SMART_ALL_DATA *stSmartAllInfo )
{   
    // 戻り値格納用
    int iResult = FALSE;

    //検索パス用
    char cppSearchPath[_MAX_PATH]={0};  

    //検索パスをコピー
    strcpy_s( cppSearchPath,cpSearchPath );

    //API関数を呼び出し、検索処理する
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind;
    strcat_s( cppSearchPath,_MAX_PATH,"\\*" );
    hFind=FindFirstFile( cppSearchPath,&FindFileData );

    if( INVALID_HANDLE_VALUE == hFind )
    {
        return FALSE;
    }
    while( TRUE )
    {
        if( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
        {
            if( FindFileData.cFileName[0] != '.' )
            {
                //フォルダは存在する場合
                char szFile[_MAX_PATH] = {0};
                strcpy_s( szFile,cpSearchPath );
                strcat_s( szFile,"\\" );

                strcat_s( szFile,FindFileData.cFileName );
                //再帰する
                iResult = FileSearch( iCount,szFile,stSmartAllInfo );   
            }
        }
        else
        {   
            //取得のファイ名 '.'以降の文字列を取得 cpstrdatに格納
            char *cpstrdat=strrchr( FindFileData.cFileName,'.' );

            //検索のファイル型の判断 .datファイルの場合 リード処理
            if(strcmp( ".dat",cpstrdat) == 0 )
            {
                if( stSmartAllInfo != NULL )
                {
                    char cppFiledatpath[_MAX_PATH] = {0};
                    strcpy_s( cppFiledatpath,cpSearchPath );
                    strcat_s( cppFiledatpath,"\\" );
                    strcat_s( cppFiledatpath,FindFileData.cFileName );
                    int iReadlost = FALSE;

                    //リード処理を実行
                    iReadlost = File_r( cppFiledatpath, stSmartAllInfo, *iCount );

                    //***ファイルオープン失敗の場合 ファイル名を出力
                    if( iReadlost == FALSE )
                    {   
                        printf( "Can not to open %s.\n", FindFileData );
                        printf( "Please make sure the FileName and FullPath.\n");
                    }
                    else
                    {
                        iResult = TRUE;
                    }
                }
                //ファイル読み込み数を+1
                *iCount = *iCount + 1;
            }
        }   
        //ファイル内の場合、Break
        if( !FindNextFile( hFind, &FindFileData ) )
            break;
    }

    return iResult;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// 関数名 : File_r
// 機能 : オープンした.datファイルを読む込み処理
// 引数 : cpSearchPath : フルパス+.datファイル名用
//        iFileNo      : ファイル個数用
//
//       stSmartAllInfo  : リードするデータを保存用             
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
int File_r( char *cpSearchPath, SMART_ALL_DATA *stSmartAllInfo, int iFileNo )
{       
    FILE *fp = NULL;

    //一ファイルリードループ用
    int iDataCnt = 0;

    //ファイルオープン
    fopen_s( &fp,cpSearchPath,"rb" );

    //エラー判断
    if( fp == NULL )
    {   
        return FALSE;                   
    }

    //ファイル名を格納
    strcpy_s( stSmartAllInfo[iFileNo].FileNames ,_MAX_PATH,cpSearchPath );

    //ファイル終端までループ
    while( !feof(fp) )
    {   
        //AttributeID~RawValueまで、一行のデータを読み込む、ファイル終端までループ
        fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].AttributeID, 1, 1, fp );
        fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].AttributeFlag, 1, 2, fp );
        fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].CurrentValue, 1, 1, fp );
        fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].WorstValue, 1, 1, fp );
        fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].ThresholdValue, 1, 1, fp );
        fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].RawValue, 1, 6, fp ); 
        //行数記録
        iDataCnt++;
    }   
    fclose( fp );

    return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
// 関数名 : FileOut
// 機能 : データを出力処理
// 引数 : cpOutFileName : 出力ファイル名用
//        iCount        : ファイル個数用
//        iOption       : オプション判断用
//       stSmartAllInfo  : データを書き込み用
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
int FileOut( char *cpOutFileName, SMART_ALL_DATA *stSmartAllInfo, int iCount, int iOption )   
{
    FILE *fp = NULL;

    //ファイル個数用
    int iFileCnt = 0;
    //行数ループ用
    int iDataCnt = 0;

    //ファイルオープン
    fopen_s( &fp, cpOutFileName, "wb" );

    //オープンエラー判断
    if( fp == NULL )
    {
        printf( " Can not to open %s.\n " ,cpOutFileName);
        return FALSE;
    }
    //ライトループ
    for( iFileCnt = 0; iFileCnt < iCount; iFileCnt++ )
    {
        fprintf( fp,"%s,",stSmartAllInfo[iFileCnt].FileNames );
        for( iDataCnt = 0; iDataCnt < SMART_DATA_MAX; iDataCnt++ )
        {
            //AttributeID "0"場合は出力しないこと
            if( stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].AttributeID !=0 )        
            {
                //オプション ORの場合:RAWデータだけ出力する
                if( iOption == OUTPUT_ORDATA )                      
                {
                    fprintf( fp,"%02x%02x%02x%02x%02x%02x," ,   stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[0],
                                                                stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[1],
                                                                stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[2],
                                                                stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[3],
                                                                stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[4],
                                                                stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[5] );
                                                    }
                //オプション OVの場合:valueデータだけ出力する
                else if( iOption == OUTPUT_OVDATA )             
                {
                    fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].CurrentValue);
                    fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].WorstValue);
                    fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].ThresholdValue);
                    fprintf(fp,"%02x%02x%02x%02x%02x%02x,", stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[0],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[1],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[2],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[3],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[4],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[5] );
                }
                //オプション RCの場合:Rawデータを逆序列出力出力する 
                else if( iOption == OUTPUT_RCDATA )             
                {
                    fprintf(fp,"%02x%02x%02x%02x%02x%02x,", stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[5],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[4],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[3],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[2],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[1],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[0] );
                }
                // 全データ出力
                else
                {   
                    fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].AttributeID );
                    fprintf(fp,"%04x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].AttributeFlag );
                    fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].CurrentValue );
                    fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].WorstValue );
                    fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].ThresholdValue );
                    fprintf(fp,"%02x%02x%02x%02x%02x%02x,", stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[0],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[1],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[2],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[3],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[4],
                                                            stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[5] );               
                }
            }
        }
        //1個ファイル出力後 改行する.
        fprintf(fp,"\r\n");
    }

    //ファイルクローズ
    fclose( fp );

    return TRUE;
}

VS2008下编译通过。

  • 写回答

1条回答 默认 最新

  • 逍遥侯之水流云 2016-06-29 00:16
    关注

    完善资料可以奖励C币,绑定手机号可以奖励c币。

    评论

报告相同问题?

悬赏问题

  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥30 用arduino开发esp32控制ps2手柄一直报错
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥20 求一个html代码,有偿