了解获取线字符串分配后的初始用户输入

Knowing initial user input after getline cstring assignment

本文关键字:用户 输入 获取 字符串 分配 了解      更新时间:2023-10-16

这是我的一个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

C 风格的终止字符串使用起来相当棘手,几乎在每种情况下,我都会推荐使用 C++ std::string。但是,既然您说您特别想将终止的字符串读入数组,这里有一种方法可以做到这一点。

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

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

while (!std::cin.getline(buffer, MAX+1)) {
    std::cout << "Too longn";
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}

使用正确的C++(特别是string s和自由getline函数(:

#include <string>
#include <iostream>
std::string line;
while (std::getline(std::cin, line))
{
    if (line.length() > 12)
    {
        // error, line too long
        continue;
    }
    // process line
}
如果您想

了解std::istream::getline()是否按要求读取充满字符但不是行尾字符的数组,您需要确定存储字符的数量(减去终止 null(是否与提取的字符相同。也就是说,下面确定行上是否有超过 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 linen";
    }
}

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

实际上,更仔细地查看规范std::istream:getline()实际上设置std::ios_base::failbit如果在读取字符时没有遇到换行符(当读取字符时,它还设置std::ios_base:failbit,但如果在到达文件末尾之前至少读取了一个字符,它不会设置std::ios_base::failbit(。这意味着,您还希望在忽略多余的字符之前清除流,并且可以std::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(),然后才能将流用于任何操作。

要使用户输入的字符数超过您允许的字符数,他必须至少超过限制一个字符。由于用户"超过"限制的字符数对您来说无关紧要,因此您可以将MAX+1作为限制传递,并查看长度是否大于 MAX

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