1

这是我的一个 C++ 函数:

void SetUserName(char username[])
{
    cout << "\nPlease enter a username.\n"
         << "Must not be longer than 12 characters.\n>> ";

    cin.getline(username, MAX) // MAX is globally defined

    while(strlen(username) > MAX)
    {
        cout << "\nUsername too long, try again.\n>> ";
        cin.getline(username, MAX);
    }
}

显然,while 循环永远不会起作用,因为用户输入每次都被截断为 12 个字符。

如何有效判断用户输入是否过长,并继续循环直到满足条件?

编辑:在此处 使用cstring是一项要求。我已经知道使用字符串是多么容易。

编辑#2:这对我来说绝对是一个富有成果的问题,因为它教会了我很多东西。最终代码: http: //pastie.org/3537894

4

4 回答 4

4

C 风格的终止字符串处理起来相当棘手,几乎在每种情况下,我都推荐使用 C++ std::string。但是,由于您说您特别想将终止的字符串读入数组,因此这是一种方法。

请记住,数组大小必须为MAX+1,因此MAX后面有终止符的字符空间。

istream::getlinefailbit如果行太长,则设置流标志;您可以在阅读后对此进行测试。如果只提取了部分行,并且您想继续下一行,那么您需要清除错误状态,并忽略该行的其余部分。

while (!std::cin.getline(buffer, MAX+1)) {
    std::cout << "Too long\n";
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
于 2012-03-06T23:46:22.230 回答
3

使用正确的 C++(特别是strings 和 freegetline函数):

#include <string>
#include <iostream>

std::string line;
while (std::getline(std::cin, line))
{
    if (line.length() > 12)
    {
        // error, line too long

        continue;
    }

    // process line
}
于 2012-03-06T23:10:48.123 回答
3

如果您想知道是否std::istream::getline()按要求读取了一个满是字符但不是行尾字符的数组,您需要确定存储的字符数(减去终止的空字符)是否与提取的字符数相同。也就是说,以下确定该行上是否有超过 12 个字符(终止 null 需要第 13 个字符):

#include <iostream>
#include <string.h>

int main()
{
    char array[13];
    if (std::cin.getline(array, 13).gcount() == strlen(array)) {
        std::cout << "excess characters on the line\n";
    }
}

如果您接下来还想从流中删除多余的字符,您可以使用类似std::cin.ignore(std::numeric_limits<std::streamsize>::max());. 由于这也被标记为 C,所以我不知道如何使用 C 来执行此操作,但我很确定有一些类似于gcount().

实际上,如果在读取字符时没有遇到换行符,更仔细地查看规范std::istream:getline()实际上会设置(它也会设置没有读取任何字符,但如果在到达文件结尾之前读取了至少一个字符,则不会设置)。这意味着,您还想在忽略多余字符之前清除流,并且您可以工作并且:std::ios_base::failbitstd::ios_base:failbitstd::ios_base::failbitstd::ios_base::failbitstd::ios_base::eof()

#include <iostream>
#include <limits>
#include <string.h>

int main()
{
    char array[13];
    std::cout << "enter password: ";
    while (!std::cin.getline(array, 13) && !std::cin.eof())
    {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "password is too long: enter max 12 chars: ";
    }
    std::cout << "the password is '" << array << "'\n";
}

由于std::ios_base::failbit已设置,您需要先调用clear(),然后才能将流用于任何事情。

于 2012-03-06T23:34:27.677 回答
1

如果用户输入的字符数超过您允许的字符数,他必须至少超出限制一个字符。由于用户“超过”限制的字符数对您来说并不重要,因此您可以将MAX+1其作为限制传递,并查看长度是否大于MAX.

当然,您需要在缓冲区中留出足够的空间来保存第 13 个字符和一个零终止符。编辑您还需要ignore在每次尝试失败时调用以跳到行尾。

于 2012-03-06T23:09:35.627 回答