簡體   English   中英

cin.getline() 不接受輸入的問題

[英]Problems with cin.getline() not accepting input

我正在使用 cin.getline() 將用戶輸入存儲在字符數組中,並嘗試解析輸入以僅允許輸入 1 到 4 之間的數字。 在一組特定的情況下一切正常:第一次嘗試輸入正確的輸入,或輸入 2 個或更少的字符,然后輸入正確的輸入。 下面是一個例子。

[Expected behavior]
Enter input: 1 [ENTER]
Input accepted

[Expected behavior]
Enter input: rw [ENTER]
Incorrect input. Please try again.
Enter input: 1 [ENTER]
Input accepted

[Unexpected behavior]
Enter Input: rtw [ENTER]
Incorrect input. Please try again.
Enter Input: 1 [ENTER]
Incorrect input. Please try again.
Enter input: 1 [ENTER]
Incorrect input. Please try again.
[This will continue indefinitely]

我已經嘗試了從清除輸入緩沖區到將字符數組重置為空終止符的所有方法,以嘗試查看它是否仍然保存來自先前輸入的值(就像在意外行為中,如果“tw”不知何故仍在內存中) . 我想我可能有與此討論類似的問題,但我不是 100% 確定。 當我嘗試清除輸入緩沖區時,它會等待第二組輸入,我不確定為什么。 當我打印inputLength的結果時,在“意外行為”運行后,它顯示數組中仍有 2 或 3 個字符,而我只輸入了 1。刪除 cin.clear()/cin.ignore() 時,不需要第二個輸入,但會發生上述行為。 我很感激任何幫助。

我在下面發布了相關代碼。

char* ValidateInput() {
    const int maxInput = 25;
    char userInput[maxInput] = { "\0" };
    int inputLength = 0;
    bool correctInputBool = false;

    while (!correctInputBool) {
        // subtract 1 to allow for null terminator at end of array
        cin.getline(userInput, (maxInput - 1), '\n');


        // I have tried both versions of cin.ignore() below, but neither works
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        //cin.ignore(numeric_limits<streamsize>::max());



        // calculate how many characters user entered
        inputLength = sizeOfCharArray(userInput, maxInput);

        // I do other things here, there isn't a problem with this. For now, assume all 1-character input is acceptable
        if (inputLength == 1) {
            cout << "Correct input." << endl;
            correctInputBool = true;
        }

        if (!correctInputBool) {
            cout << "Sorry, that input is incorrect. Please try again." << endl;
            cout << "Please enter a number between 1 and 4." << endl;
        }
        return userInput;
    }

int sizeOfCharArray(char input[], int maxSize) {
    // all values in input are set to "\0", so count all characters that are not null
    int userSize = 0;
    for (int index = 0; index < maxSize; index++) {
        if (input[index] != '\0') {
            userSize++;
        }
    }
    return userSize;
}

編輯:我注意到當我輸入超過 3 個字符時,下一次運行將始終將inputLength降低一個值。 再次要求輸入時,輸入 9 個字符會減少到 8 個,即使只輸入了1

我能夠使用 Visual Studio 並觀察inputLengthuserInput變量。 inputLength確實只下降了 1 個值,因為在輸入的末尾添加了一個空終止符。 因為這

userInput = "asdf" // with the reminaing values being '\0'
inputLength = 4

userInput = "2'\0'df" // with the following being held in memory: 2 '\0' df '\0' '\0' . . .
inputLength = 3

當我嘗試打印 userInput 的值時,由於空終止符,我只看到了2 即使值仍然存在,它們也不會打印,因為編譯器看到'\\0' ,並且認為之后沒有任何內容。 結果,當我調用sizeOfCharArray ,所有不是空終止符的值都被計算在內,其中包括來自先前輸入的值。

我更新的代碼如下。

char* ValidateInput() {
    const int maxInput = 25;
    char userInput[maxInput] = { "\0" };
    int inputLength = 0;
    bool correctInputBool = false;

    while (!correctInputBool) {         
        // updated section
        for (int index = 0; index < maxInput; index++) {
            userInput[index] = '\0';
        }
        // subtract 1 to allow for null terminator at end of array
        cin.getline(userInput, (maxInput - 1), '\n');

        // calculate how many characters user entered
        inputLength = sizeOfCharArray(userInput, maxInput);

        // I do other things here, there isn't a problem with this. For now, assume all 1-character input is acceptable
        if (inputLength == 1) {
            cout << "Correct input."
            correctInputBool = true;
        }

        if (!correctInputBool) {
            cout << "Sorry, that input is incorrect. Please try again." << endl;
            cout << "Please enter a number between 1 and 4." << endl;
        }
        return userInput;
    }

int sizeOfCharArray(char input[], int maxSize) {
    // all values in input are set to "\0", so count all characters that are not null
    int userSize = 0;
    for (int index = 0; index < maxSize; index++) {
        if (input[index] != *"\0") {
            userSize++;
        }
    }
    return userSize;
}

您的代碼中存在多個問題,您遲早會發現這些問題。

順便提一句。 您當前的代碼無法編譯。 我假設你確實有; cout << "Correct input."之后cout << "Correct input." ifreturn大括號之間的} ,否則您的示例將永遠不會循環一次。

您提到的問題

您沒有清除userInput (並且您的sizeOfCharArray沒有為此做好准備)。

讓我們一步一步地使用您的代碼:

  1. userInput[maxInput] = { "\\0" }; //userInput contains all null characters
  2. 用戶輸入rwt
  3. userInput包含"rwt\\0"
  4. 您的代碼正確地將其視為無效輸入並再次要求輸入
  5. 用戶輸入1
  6. userInput被用戶輸入的字符串覆蓋,但它不會被預先清除 它現在包含1\\0t\\0
  7. sizeOfCharArray計算所有非空字符並返回 2。
  8. 您的循環繼續要求輸入。

你返回局部變量的地址

ValidateInput之后, userInput數組已死。 一去不復返。 然后你將地址返回到一個死數組,一個可以被編譯器隨意使用的內存。

你的代碼太復雜了

這通常是一個被低估的問題,但簡單的代碼 = 易於閱讀 = 更少的錯誤。

你想要一個整數,對吧? 那么如何從 input 中讀取一個整數呢?

int GetInput() {
    int result {};
    while (true) { //infinite loop
        cin >> result;

        if(!cin.good()) {
            cout << "Input wasn't a number, please try again.\n";
            cin.clear(); //clear flags that were raised
            cin.ignore(numeric_limits<streamsize>::max(), '\n'); // skip any input remaining in the stream
        } else if (!InputIsValid(result)) {
            cout << "Input not in 1-4 range, please try again.\n";
        } else {
            return result;
        }
    }
}

bool InputIsValid(int input) {
    return input >= 1 && input <= 4;
}

std::cin未能提取所請求的類型(在本例中為int )並且變量為零(自 C++11 起),則std::cin將引發其fail位。 如果設置了fail位, good()方法將返回false (即流狀態不佳)。 在下一次迭代中,我們清除流中的標志和任何剩余的輸入。
您還可以檢查循環中整數的有效范圍(此處作為單獨的函數完成)。

我們使用return語句跳出循環。 如果一切都正確(即流設法讀取正確類型的輸入並且輸入在有效范圍內),我們將最終值返回給用戶。


與 qoutes 相關的問題: 單引號 vs. C 或 C++ 中的雙引號 請為了您自己的心理健康,在編譯器停止顯示錯誤之前不要隨意添加符號,這絕不是一個好主意。 編譯器是你的朋友,他會幫助你發現問題,但前提是你幫助它做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM