【问题标题】:ADO Recordset Field Value to C++ vector/array (capture pointer value)ADO 记录集字段值到 C++ 向量/数组(捕获指针值)
【发布时间】:2016-03-05 23:51:51
【问题描述】:

我正在尝试通过 Visual C++ (express) 查询 SQL Server (Express) 并将结果数据集存储到 C++ 向量中(数组也很好)。为此,我研究了 ADO 库,并在 MSDN 上找到了很多帮助。简而言之,参考 msado15.dll 库并使用这些功能(尤其是 ADO Record Binding,它需要 icrsint.h)。简而言之,我已经能够使用 printf() 查询数据库并显示字段值;但是当我尝试将字段值加载到向量中时,我绊倒了。

我最初尝试通过将所有内容强制转换为 char* 来加载值(由于许多类型转换错误后的绝望),结果发现最终结果是一个指针向量,它们都指向相同的内存地址。接下来(这是下面提供的代码)我试图分配内存位置的值,但最终只得到了内存位置第一个字符的向量。简而言之,我需要帮助了解如何传递由 Recordset 字段值 (rs.symbol) 指针(在传递给向量时)存储的整个值,而不仅仅是第一个字符?在这种情况下,SQL 返回的值是字符串。

#include "stdafx.h"
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")
#include "iostream"
#include <icrsint.h>
#include <vector>
int j;
_COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding));
inline void TESTHR(HRESULT _hr) { if FAILED(_hr) _com_issue_error(_hr); }
class CCustomRs : public CADORecordBinding {
    BEGIN_ADO_BINDING(CCustomRs)
        ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, symbol, sizeof(symbol), symbolStatus, false)
        END_ADO_BINDING()
public:
    CHAR symbol[6];
    ULONG symbolStatus;
};
int main() {
    ::CoInitialize(NULL);
    std::vector<char> tickers;
    try {
        char sym;
        _RecordsetPtr pRs("ADODB.Recordset");
        CCustomRs rs;
        IADORecordBindingPtr picRs(pRs);
        pRs->Open(L"SELECT symbol From Test", L"driver={sql server};SERVER=(local);Database=Securities;Trusted_Connection=Yes;", 
            adOpenForwardOnly, adLockReadOnly, adCmdText);
        TESTHR(picRs->BindToRecordset(&rs));
        while (!pRs->EndOfFile) {
            // Process data in the CCustomRs C++ instance variables.
//Try to load field value into a vector
            printf("Name = %s\n",
                (rs.symbolStatus == adFldOK ? rs.symbol: "<Error>"));


//This is likely where my mistake is
sym = *rs.symbol;//only seems to store the first character at the pointer's address


            // Move to the next row of the Recordset.   Fields in the new row will 
            // automatically be placed in the CCustomRs C++ instance variables.
//Try to load field value into a vector
            tickers.push_back (sym); //I can redefine everything as char*, but I end up with an array of a single memory location...
            pRs->MoveNext();
        }
    }
    catch (_com_error &e) {
        printf("Error:\n");
        printf("Code = %08lx\n", e.Error());
        printf("Meaning = %s\n", e.ErrorMessage());
        printf("Source = %s\n", (LPCSTR)e.Source());
        printf("Description = %s\n", (LPCSTR)e.Description());
    }
    ::CoUninitialize();
//This is me running tests to ensure the data passes as expected, which it doesn't
    std::cin.get();
    std::cout << "the vector contains: " << tickers.size() << '\n';
    std::cin.get();
    j = 0;
    while (j < tickers.size()) {
        std::cout << j << ' ' << tickers.size() << ' ' << tickers[j] << '\n';
        j++;
    }
    std::cin.get();
}

感谢您提供的任何指导。

【问题讨论】:

    标签: c++ ado data-conversion


    【解决方案1】:

    std::vector&lt;char*&gt; 不起作用,因为所有记录都使用同一个缓冲区。所以当pRs-&gt;MoveNext()被调用时,新的内容会被加载到缓冲区中,覆盖之前的内容。

    您需要复制内容。

    我建议使用std::vector&lt;std::string&gt;:

    std::vector<std::string> tickers;
    ...
    
        tickers.push_back(std::string(rs.symbol));
    

    【讨论】:

    • 嘿阿兰(我没有对此投反对票,仅供参考)-我接受了您的建议,并按照您提到的重新调整了代码向量和 push_back 行。但是,当我让程序使用 printf("%s\n", tickers[j]); 打印结果向量中的值时存储在向量中的值似乎是乱码......我在这里错过了什么吗?
    • 您可以在问题中使用cout &lt;&lt; ,也可以使用printf("%s\n", tickers[j].c_str());。我知道你没有投反对票,我想这是因为我在 meta 上写的评论。
    • Gotcha - 我将不得不进行更多研究以了解为什么我们需要使用 .c_str() 方法/属性(我当然可以推测)。但是让我告诉你,我已经为此苦苦挣扎了一段时间,而你刚刚完成了我的一周!
    • :-) 谢谢。 printf 是 C 函数,string 是 C++ 的东西。 c_str() 给你一个 C 风格的字符串。
    【解决方案2】:

    为什么你不使用std::string 而不是std::vector? 要添加字符,请使用以下成员函数之一: basic_string&amp; append( const CharT* s ); - 对于 cstrings, basic_string&amp; append( const CharT* s,size_type count ); - 否则。 阅读更多:http://en.cppreference.com/w/cpp/string/basic_string/append

    如果你想要换行,只需在你想要的地方追加'\n'

    【讨论】:

    • 不确定我是否理解这一点。我想使用一个数组,因为我将有很多元素——然后该数组/向量将用于创建其他数组/向量;所以我想使用向量来帮助管理工作流程。我不希望这里有一个长字符串。
    • 是的,string.append 用于将单个字符附加到字符串,所以这在这里不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 2015-05-24
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    相关资源
    最近更新 更多