月望村吧 关注:3贴子:696

cin 和cin.get()以及cin.getline()对于'\n'及其返回值问题

只看楼主收藏回复

在 C++ 中,cin.getline() 函数用于从输入流中读取一行字符,并在读取到换行符 \n 时停止。这种读取会自动丢弃(忽略)换行符,不会保留在输入流中,因此不会对后续的读取操作造成干扰。
————————————————————————————————
连续两次使用 cin.getline() 的行为
如果你连续两次调用 cin.getline(),每次都从输入流中读取一行字符,并且用 cout 显示这些读取的内容,由于 cin.getline() 自动丢弃换行符,两次读取的内容将会分别显示在不同的行上。
————————————————————————————————
示例分析
让我们看一个具体的例子:
#include <iostream>
int main() {
const int MAX_LENGTH = 100;
char line1[MAX_LENGTH];
char line2[MAX_LENGTH];
// 读取第一行
std::cout << "Enter the first line: ";
std::cin.getline(line1, MAX_LENGTH);
// 读取第二行
std::cout << "Enter the second line: ";
std::cin.getline(line2, MAX_LENGTH);
// 输出两行内容
std::cout << "First line: " << line1 << std::endl;
std::cout << "Second line: " << line2 << std::endl;
return 0;
}


IP属地:江苏1楼2024-06-16 21:23回复
    在这个示例中:
    第一次调用 std::cin.getline(line1, MAX_LENGTH),会读取用户输入的第一行文本,并且在遇到换行符时停止并丢弃换行符。
    第二次调用 std::cin.getline(line2, MAX_LENGTH),会读取用户输入的第二行文本,行为同样是读取到换行符并丢弃它。
    最后用 std::cout 输出这两行读取的内容。


    IP属地:江苏2楼2024-06-16 21:24
    回复
      假设用户的输入是:
      Hello, this is the first line.
      And this is the second line.
      程序的输出将是:
      Enter the first line: Hello, this is the first line.
      Enter the second line: And this is the second line.
      First line: Hello, this is the first line.
      Second line: And this is the second line.
      ——————————————————————————
      为什么每行内容会在 cout 中显示在不同的行?
      std::cin.getline() 的行为是读取一行字符,并丢弃遇到的换行符。
      由于换行符被丢弃,输入流在第二次调用 std::cin.getline() 时是清洁的,并准备读取下一行的内容。
      在输出时,std::cout 会按照 std::endl 输出换行符,因此每次 std::cout << lineX << std::endl; 会在 lineX 的内容之后添加一个换行符。


      IP属地:江苏3楼2024-06-16 21:28
      回复
        更详细的解释
        cin.getline() 是专门设计来处理行输入的工具,它会读取字符直到遇到换行符。换行符不会包括在结果中,也不会留在输入流中。因为每次调用 getline 后输入流状态被恢复到准备读取下一行的状态,因此后续的读取是独立的,不会受到前一次输入的换行符的影响。


        IP属地:江苏4楼2024-06-16 21:28
        回复
          对比 cin 和 cin.get()
          与 cin.getline() 不同,cin 和某些 cin.get() 的重载版本会在读取操作后留下换行符在输入流中。如果不清理这些剩余的换行符,后续的读取操作可能会遇到意外的行为:
          ——————————————————————————————————
          #include <iostream>
          int main() {
          char line1[100];
          char line2[100];
          // 使用 cin 读取第一行,换行符将保留在输入流中
          std::cout << "Enter the first line: ";
          std::cin >> line1;
          // 使用 cin.getline() 读取第二行,将直接读取之前的换行符
          std::cout << "Enter the second line: ";
          std::cin.getline(line2, 100);
          std::cout << "First line: " << line1 << std::endl;
          std::cout << "Second line: " << line2 << std::endl;
          return 0;
          }


          IP属地:江苏5楼2024-06-16 21:30
          收起回复
            总结
            使用 cin.getline() 可以方便地读取一行输入并自动丢弃换行符。
            连续调用 cin.getline() 读取的每一行内容都是独立的,不会受到前一次输入换行符的影响。
            当在 cin.getline() 之间使用其他读取方法时,需小心处理换行符,以避免意外行为。


            IP属地:江苏6楼2024-06-16 21:35
            回复
              在 C++ 中,cin 读取操作的行为取决于具体使用的函数或操作符。不同的读取方式会有不同的处理空白字符(如空格、制表符和换行符)的行为。以下是对几种常用 cin 读取方法如何处理空白字符的详细说明:
              ————————————————————————————
              cin >> 操作符
              使用 cin >> 读取输入时,空白字符(空格、制表符和换行符)会被自动跳过,直到遇到第一个非空白字符为止。这意味着 cin >> 适用于读取单个单词或数字。
              ————————————————————————————
              #include <iostream>
              int main() {
              std::string word;
              std::cout << "Enter a word: ";
              std::cin >> word;
              std::cout << "You entered: " << word << std::endl;
              return 0;
              }


              IP属地:江苏7楼2024-06-16 21:37
              收起回复
                cin.get()
                cin.get() 的不同重载版本处理空白字符的方式不同。我们重点关注两种常用的重载:
                ————————————————————————————
                std::cin.get(char& ch)
                读取一个字符,包括空白字符。
                不跳过空白字符或换行符。
                #include <iostream>
                int main() {
                char ch;
                std::cout << "Enter a character: ";
                std::cin.get(ch);
                std::cout << "You entered: " << ch << std::endl;
                return 0;
                }


                IP属地:江苏8楼2024-06-16 21:40
                收起回复
                  std::cin.get(char* s, streamsize n)
                  读取最多 n-1 个字符,直到遇到换行符或达到字符数限制。
                  换行符不会包括在结果中,但会保留在输入流中供后续处理。
                  ——————————————————————————
                  #include <iostream>
                  int main() {
                  char buffer[100];
                  std::cout << "Enter a line (up to 99 characters): ";
                  std::cin.get(buffer, 100);
                  std::cout << "You entered: " << buffer << std::endl;
                  return 0;
                  }


                  IP属地:江苏9楼2024-06-16 21:42
                  收起回复
                    cin.getline()
                    cin.getline() 读取整行文本,包括空白字符,直到遇到换行符。换行符会被丢弃,不会保留在输入流中。
                    ————————————————————————————
                    #include <iostream>
                    int main() {
                    char buffer[100];
                    std::cout << "Enter a line: ";
                    std::cin.getline(buffer, 100);
                    std::cout << "You entered: " << buffer << std::endl;
                    return 0;
                    }


                    IP属地:江苏10楼2024-06-16 21:44
                    收起回复
                      std::getline()
                      std::getline() 是用于从 std::istream 读取整行文本到 std::string 中的函数。它类似于 cin.getline(),但适用于 std::string。
                      ————————————————————————
                      #include <iostream>
                      #include <string>
                      int main() {
                      std::string line;
                      std::cout << "Enter a line: ";
                      std::getline(std::cin, line);
                      std::cout << "You entered: " << line << std::endl;
                      return 0;
                      }


                      IP属地:江苏11楼2024-06-16 21:46
                      收起回复
                        总结
                        cin >>:跳过所有前导空白字符(包括空格、制表符和换行符),只读取非空白字符到下一个空白字符或流结束。
                        cin.get():读取单个字符或指定数量的字符,不跳过空白字符,包括换行符。
                        cin.getline() 和 std::getline():读取一行字符直到遇到换行符,并丢弃换行符。前导空白字符不会被跳过。


                        IP属地:江苏12楼2024-06-16 21:47
                        回复
                          当你使用 cin 来读取输入时,通常会留下换行符在输入流中。这种情况会影响后续的 cin.get() 或 cin.getline() 操作,因为这些操作会立即遇到并处理掉这个残留的换行符,从而导致它们的行为与预期不符。
                          ——————————————————————
                          具体原因和影响
                          当你使用 cin 读取字符串(例如通过 std::cin >> str),它会读取到空白字符(如空格或换行符)为止,但不会读取并移除这些空白字符。如果读取的输入后面有换行符,这个换行符将保留在输入流中。因此,后续的 cin.get() 或 cin.getline() 操作会在开始时直接遇到这个换行符,从而导致以下行为:
                          cin.get(char& ch) 直接读取并返回这个换行符字符。
                          cin.getline(char* s, streamsize n) 读取到这个换行符后,认为已经读取到了一行的结尾,并将其丢弃,导致它只读取到一个空行。


                          IP属地:江苏13楼2024-06-16 21:48
                          回复
                            问题示例
                            ——————————————
                            #include <iostream>
                            #include <string>
                            int main() {
                            std::string name;
                            char buffer[100];
                            std::cout << "Enter your name: ";
                            std::cin >> name;
                            // 读取第二行
                            std::cout << "Enter a sentence: ";
                            std::cin.getline(buffer, 100);
                            std::cout << "Name: " << name << std::endl;
                            std::cout << "Sentence: " << buffer << std::endl;
                            return 0;
                            }


                            IP属地:江苏14楼2024-06-16 21:48
                            收起回复
                              结果,输出的句子是空的:
                              Enter your name: Alice
                              Enter a sentence:
                              Name: Alice
                              Sentence:
                              解决方案:清除换行符
                              为了正确处理这个问题,在调用 std::cin.get() 或 std::cin.getline() 之前,应该清除输入流中残留的换行符。这可以通过 std::cin.ignore() 函数来实现:
                              ————————————————————————
                              #include <iostream>
                              #include <string>
                              int main() {
                              std::string name;
                              char buffer[100];
                              std::cout << "Enter your name: ";
                              std::cin >> name;
                              // 清除输入流中的换行符
                              std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                              // 读取第二行
                              std::cout << "Enter a sentence: ";
                              std::cin.getline(buffer, 100);
                              std::cout << "Name: " << name << std::endl;
                              std::cout << "Sentence: " << buffer << std::endl;
                              return 0;
                              }


                              IP属地:江苏15楼2024-06-16 21:51
                              收起回复