2012-02-10 54 views
0

我需要在C++/ODBC應用程序中擺脫固定數組大小。 而不是硬編碼的數組大小(ROWS = 10以下)我想通過ROWS作爲命令行參數。我知道如何解析命令行。 但是如何調整下面的代碼?如何重構C++代碼以支持動態數組大小

 
    #define ROWS 10 

    SQLINTEGER idata[ROWS] 
    SQLCHAR cdata1[ROWS][256] 
    SQLFLOAT fdata[ROWS] 
    SQL_TIMESTAMP_STRUCT ts[ROWS] 

    SQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, ROWS) 

    SQLBindCol(1, &idata) 
    SQLBindCol(2, cdata1) 
    SQLBindCol(3, fdata) 
    SQLBindCol(4, &ts) 
    SQLExecDirect("query producing a result-set") 

更新:我不能修改SQLBindCol的簽名(..)

讓我們說,我將創建的std ::載體,而不是SQLFLOAT FDATA [行數],但如何將其傳遞到SQLBindCol(),它不指望std :: vector?

+4

你不能有變長數組在C++中數組的長度必須是一個編譯時constant.You可能要考慮使用'性病的動態二維陣列的解決方案: :vector'或'std :: array'而不是c-style數組。 – 2012-02-10 06:28:34

+2

C++不提供可變長度的數組,但它們當然不必是編譯時常量。這就是'new []'的用途。例如'SQLINTEGER * idata = new SQLINTEGER [rows]'(並且不要忘記稍後'delete []')。多維數組cdata1是一個更大的問題,因爲它不能動態分配。你可以做的最好的是一個數組或一個新的SQLCHAR [rows * 256],其中一個可能會工作,這取決於SQLBindCol在這裏的工作方式。我對ODBC的瞭解還不夠多,不僅如此。 – 2012-02-10 06:48:02

回答

1

fdata使用std::vector

size_t rowCount = /* ... */; 
std::vector<SQLFLOAT> fdata(rowCount); 
// ... 
SQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, rowCount); 
// ... 
SQLBindCol(3, &fdata[0]); 
// ... 

對於cdata1std::vector<SQLCHAR> cdata1(250 * rowCount);可能會奏效。

0

使用指針。

如您所說,接受來自命令行的ROWS參數。通過使用malloc/new來分配所有已聲明的變量(如idata,cdata1等),使用動態內存分配分配所需大小的內存(ROWS參數)。就是這樣!

0

我還沒有設法使它與2d動態數組一起工作。 但這裏是一個使用一維數組

std::set<std::string> getResults(int columnIndex, HSTMT stmt) { 
    std::set<std::string> results; 
    RETCODE rc = 0; 
    int rows = 250; 
    int colsize = 500 + 1; //Need to increment colunm size by 1 because SQLBindCol add the terminator character "\0" 

    SQLLEN *indicator1 = new SQLLEN[rows]; 
    char *buff = new char[rows*colsize]; 
    SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)rows, 0); 

    SQLUINTEGER  NumRowsFetched; 
    SQLSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &NumRowsFetched, 0); 

    SQLBindCol(stmt, columnIndex, SQL_C_CHAR, buff, colsize, indicator1); 
    while (rc = SQLFetch(stmt) == SQL_SUCCESS) { 
     for (int i = 0; (SQLUINTEGER)i < NumRowsFetched; i++) { 
      results.insert(&buff[i * colsize]); 
     } 
    } 
    delete[] buff; 
    return results; 

}