简体   繁体   English

如何遍历 CString 并将其字符与 int 进行比较?

[英]How can I iterate over CString and compare its characters to int?

I'm writing a dialog based MFC application in Visual Studio 2017 in C++.我正在用 C++ 在 Visual Studio 2017 中编写一个基于对话框的 MFC 应用程序。 In the dialog I added a list control where the user can change the values of the cells as shown in the picture below:在对话框中,我添加了一个列表控件,用户可以在其中更改单元格的值,如下图所示: 在此处输入图片说明

after he changes the values, I want to check if those values are valid (so if he accidentally pressed the wrong button he will be notified).在他更改值后,我想检查这些值是否有效(所以如果他不小心按错了按钮,他会收到通知)。 For this purpose I'm iterating over the different cells of the list and from each cell I extract the text which is written in it into a CString type variable.为此,我迭代列表的不同单元格,并从每个单元格中提取写入其中的文本到CString类型变量中。 I want to check that this variable has only 8 characters which are '1' or '0'.我想检查这个变量是否只有 8 个字符,它们是“1”或“0”。 The problem with the code I've written is that I get weird values when I try to print the different characters of the CString variable.我编写的代码的问题在于,当我尝试打印CString变量的不同字符时,我得到了奇怪的值。

The Code for checking the validity of the CString :检查CString有效性的代码:

void CEditableListControlDlg::OnBnClickedButton4()
{
    // TODO: Add your control notification handler code here

    // Iterate over the different cells
    int bit7Col = 2;
    int bit6Col = 3;
    int bit5Col = 4;
    int bit4Col = 5;
    int bit3Col = 6;
    int bit2Col = 7;
    int bit1Col = 8;
    int bit0Col = 9;

    for (int i = 0; i < m_EditableList.GetItemCount(); ++i) {
        CString bit7 = m_EditableList.GetItemText(i, bit7Col);
        CString bit6 = m_EditableList.GetItemText(i, bit6Col);
        CString bit5 = m_EditableList.GetItemText(i, bit5Col);
        CString bit4 = m_EditableList.GetItemText(i, bit4Col);
        CString bit3 = m_EditableList.GetItemText(i, bit3Col);
        CString bit2 = m_EditableList.GetItemText(i, bit2Col);
        CString bit1 = m_EditableList.GetItemText(i, bit1Col);
        CString bit0 = m_EditableList.GetItemText(i, bit0Col);      

        CString cvalue = bit7 + bit6 + bit5 + bit4 + bit3 + bit1 + bit0;
        
        std::string value((LPCSTR)cvalue);

        int length = value.length();

        if (length != 7) {
            MessageBox("Register Value Is Too Long", "Error");
            return;
        }

        
        for (int i = 0; i < length; i++) {
            if (value[i] != static_cast<char>(0) || value[i] != static_cast<char>(1)) {
                    char c = value[i];
                    MessageBox(&c, "value"); // this is where I try to print the value
                    return;
            }
        }
    }
}

Picture of what get's printed in the message box when I try to print one character of the variable value .当我尝试打印变量value一个字符时,消息框中打印的内容的图片。 I expect to see '1' but instead I see in the message box '1iiiiii`:我希望看到“1”,但我在消息框中看到“1iiiiii”: 在此处输入图片说明

I've tried extracting the characters directly from the variable cvalue of type CString like this:我试过直接从CString类型的变量cvalue中提取字符,如下所示:

cvalue[i]

and it's length I got by using这是我通过使用得到的长度

strlen(cvalue[i])

but I've got the same result.但我得到了同样的结果。 I've also tried accessing the characters in the variable cvalue of type CString as follows:我还尝试访问CString类型的变量cvalue中的字符,如下所示:

cvalue.GetAt(i)

and to get it's length by using: cvalue.GetLength()并使用以下方法获取它的长度: cvalue.GetLength()

But again, I've got the same results.但同样,我得到了相同的结果。

Perhaps anyone could advice me how can I check that the characters in the variable cvalue of type CString are '0' or '1'?也许有人可以建议我如何检查CString类型的变量cvalue中的字符是“0”还是“1”?

Thank you.谢谢你。

You don't need to use std::string to process your strings in this case: CString works fine.在这种情况下,您不需要使用std::string来处理您的字符串: CString工作正常。

Assuming that your CString cvalue is the string you want to check, you can write a simple loop like this:假设您的CString cvalue是您要检查的字符串,您可以编写一个简单的循环,如下所示:

// Check cvalue for characters different than '0' and '1'
for (int i = 0; i < cvalue.GetLength(); i++)
{
    TCHAR currChar = cvalue.GetAt(i);
    if ((currChar != _T('0')) && (currChar != _T('1')))
    {
        CString message;
        message.Format(_T("Invalid character at position %d : %c"), i, currChar);
        MessageBox(message, _T("Error"));
    }
}

The reason for the apparently weird output in your case is that you are passing a pointer to a character that is not followed by a null-terminator:在您的案例中出现明显奇怪的输出的原因是您传递了一个指向后面没有空终止符的字符的指针:

// Wrong code
char c = value[i];
MessageBox(&c, "value");

If you don't want to build a CString with a formatted message containing the offending character, like I did in the previous sample code, an alternative could be creating a simple raw char array storing the character you want to output followed by the null-terminator:如果您不想使用包含违规字符的格式化消息构建CString ,就像我在前面的示例代码中所做的那样,另一种方法是创建一个简单的原始char数组,存储要输出的字符,后跟空字符-终结者:

// This is an array storing two chars: value[i] followed by '\0' (null)
char s[2] = {value[i], '\0'};

MessageBox(s, "value");

PS I used TCHAR in my code sample instead of char , to make the code more easily portable to Unicode builds. PS我在我的代码示例中使用了TCHAR而不是char ,以使代码更容易移植到 Unicode 版本。 Think of TCHAR as a preprocessor macro that maps to char for ANSI/MBCS builds (which seems your current case), and to wchar_t for Unicode builds.TCHAR视为预处理器宏,它映射到 ANSI/MBCS 构建的char (这似乎是您当前的情况),以及映射到 Unicode 构建的wchar_t


A Brief Note on Validating User Input关于验证用户输入的简要说明

With the above answer, I tried to strictly address your specific problem with CString character validation.有了上面的答案,我试图通过CString字符验证来严格解决您的具体问题。 But, if you can take a look from a broader perspective, I would definitely consider validating the user input before storing it in the list-view control.但是,如果您可以从更广泛的角度来看一看,我肯定会考虑在将用户输入存储到列表视图控件之前对其进行验证 For example, you could handle the LVN_ENDLABELEDIT notification from the list-view control, and reject invalid input values.例如,您可以处理来自列表视图控件的LVN_ENDLABELEDIT通知,并拒绝无效的输入值。

Or, considering that the only valid values for each bit are 0 and 1, you could let the user select them from a combo-box .或者,考虑到每个位的唯一有效值是 0 和 1,您可以让用户从组合框中选择它们。

Doing that starting from the MFC's CListCtrl is non-trivial work;从 MFC 的CListCtrl开始执行此操作是一项非常重要的工作; so, you may also consider using other open-source controls, like this CGridListCtrlEx control available from CodeProject .因此,您还可以考虑使用其他开源控件,例如CGridListCtrlEx提供的CGridListCtrlEx控件

As you write in your last paragraph, "check that the characters in the variable cvalue of type CString are '0' or '1' ?".正如您在最后一段中所写,“检查CString类型的变量cvalue中的字符是'0'还是'1' ?”。

That's exactly how.正是如此。 '0' is the character 0. But you check for the integer 0 , which is equal to the character '\\0' . '0'是字符 0。但是您检查整数0 ,它等于字符'\\0' That's the end-of-string character.那是字符串的结尾字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM