如何在 C++ 中使用 std::getline()?

在本文中,我们将了解如何在C++中使用函数std::getline()。如果您想从输入流中读取字符,这是一个非常方便的函数。

让我们通过一些说明性的例子来了解如何正确地使用它。


C++中std::getline()的基本调用

此函数用于从输入流中读取字符,并将其放入字符串

我们需要导入头文件<字符串>,因为getline()是该文件的一部分。

虽然这需要模板参数,但我们将重点介绍字符串输入(字符),因为输出是写入字符串的。

1istream& getline(istream& input_stream, string& output, char delim);

这就是说,getline()接受一个输入流,并将其写入output。分隔符可以使用delim指定。

这也会返回对相同输入流的引用,但对于大多数情况,我们不需要这个句柄。

使用std::getline()读取输入流

现在我们已经了解了基本语法,让我们将std::cin(标准输入流)的输入转换为一个字符串。

 1#include <iostream>
 2#include <string>
 3
 4int main() {
 5    // Define a name (String)
 6    std::string name;
 7
 8    std::cout << "Enter the name: ";
 9
10    // Get the input from std::cin and store into name
11    std::getline(std::cin, name);
12
13    std::cout << "Hello " << name << "!\n";
14
15    return 0;
16}

输出

1Enter the name: JournalDev
2Hello JournalDev!

事实上,我们能够从std::cin中获得输入,没有任何问题!

现在我们再举一个例子,我们有一个input.txt文件,其中包含以下内容:

1$ cat input.txt
2Hello from JournalDev
3Second Line of file
4Last line

现在让我们逐行读取文件并将它们存储到字符串的vector中!

核心逻辑是使用std::getline(文件)持续读取,直到输入流达到EOF

我们可以很容易地使用以下格式编写代码:

 1std::ifstream infile("input.txt");
 2
 3// Temporary buffer
 4std::string temp;
 5
 6// Get the input from the input file until EOF
 7while (std::getline(infile, temp)) {
 8  // Add to the list of output strings
 9  outputs.push_back(temp);
10}

完整代码如下所示:

 1#include <iostream>
 2#include <string>
 3#include <vector> // For std::vector
 4#include <fstream> // For std::ifstream and std::ofstream
 5
 6int main() {
 7    // Store the contents into a vector of strings
 8    std::vector<std::string> outputs;
 9
10    std::cout << "Reading from input.txt....\n";
11
12    // Create the file object (input)
13    std::ifstream infile("input.txt");
14
15    // Temporary buffer
16    std::string temp;
17
18    // Get the input from the input file until EOF
19    while (std::getline(infile, temp)) {
20        // Add to the list of output strings
21        outputs.push_back(temp);
22    }
23
24    // Use a range-based for loop to iterate through the output vector
25    for (const auto& i : outputs)
26        std::cout << i << std::endl;
27
28    return 0;
29}

输出

1Reading from input.txt....
2Hello from JournalDev
3Second Line of file
4Last line

在C++中使用std::getline()使用分隔符拆分输入

我们也可以使用delim参数来使getline 函数按照分隔符来拆分输入。

默认分隔符为\n(换行符)。我们可以将其更改为使getline()也根据其他字符拆分输入!

让我们在上面的例子中将delim字符设置为空格‘’字符,看看会发生什么!

 1#include <iostream>
 2#include <string>
 3#include <vector> // For std::vector
 4#include <fstream> // For std::ifstream and std::ofstream
 5
 6int main() {
 7    // Store the contents into a vector of strings
 8    std::vector<std::string> outputs;
 9
10    std::cout << "Reading from input.txt....\n";
11
12    // Create the file object (input)
13    std::ifstream infile("input.txt");
14
15    // Temporary buffer
16    std::string temp;
17
18    // Get the input from the input file until EOF
19    while (std::getline(infile, temp, ' ')) {
20        // Add to the list of output strings
21        outputs.push_back(temp);
22    }
23
24    // Use a range-based for loop to iterate through the output vector
25    for (const auto& i : outputs)
26        std::cout << i << std::endl;
27
28    return 0;
29}

输出

 1Reading from input.txt....
 2Hello
 3from
 4JournalDev
 5Second
 6Line
 7of
 8file
 9Last
10line

现在,我们有了自己的空间分隔线!


使用std::getline()可能存在的问题

虽然std::getline()是一个非常有用的函数,但在与std::cin等输入流一起使用时,可能会遇到一些问题。

  • std::getline()不会 忽略任何前导空格/换行符。

因此,如果您在getline()之前调用std::Cin>>var;,则在读取输入变量后,输入流中仍会保留一个换行符。

因此,如果您在cin之后立即调用getline(),您将得到一个换行符,因为它是输入流中的第一个字符!

要避免这种情况,只需添加一个伪std::getline()来使用这个换行符!

下面的程序显示了在getline()之前使用cin的问题。

 1#include <iostream>
 2#include <string>
 3
 4int main() {
 5    // Define a name (String)
 6    std::string name;
 7
 8    int id;
 9
10    std::cout << "Enter the id: ";
11
12    std::cin >> id;
13
14    std::cout << "Enter the Name: ";
15
16    // Notice std::cin was the last input call!
17    std::getline(std::cin, name);
18
19    std::cout << "Id: " << id << std::endl;
20    std::cout << "Name: " << name << "\n";
21
22    return 0;
23}

输出

1Enter the id: 10
2Enter the Name: Id: 10
3Name:

请注意,我根本无法输入名称!因为输入流中有一个尾随的换行符,所以它只是接受它,因为它是一个换行符,所以它停止了读取!

现在,让我们在实际的std::getline()之前添加一个伪std::getline()调用。

 1#include <iostream>
 2#include <string>
 3
 4int main() {
 5    // Define a name (String)
 6    std::string name;
 7
 8    int id;
 9
10    std::cout << "Enter the id: ";
11
12    std::cin >> id;
13
14    std::cout << "Enter the Name: ";
15
16    // Add a dummy getline() call
17    std::getline(std::cin, name);
18    // Notice std::cin was the last input call!
19    std::getline(std::cin, name);
20
21    std::cout << "Id: " << id << std::endl;
22    std::cout << "Name: " << name << "\n";
23
24    return 0;
25}

输出

1Enter the id: 10
2Enter the Name: JournalDev
3Id: 10
4Name: JournalDev

我们终于修复了我们的错误!这希望能让您在盲目使用std::getline()之前多想一想。

不幸的是,在C++中没有优雅的方法来获取输入,所以我们只能凑合着使用我们所拥有的!


总结

在本文中,我们了解了如何在C++中使用std::getline()。我们还将通过一些例子来说明此功能的威力和缺陷。

参考文献


Published At
Categories with 技术
Tagged with
comments powered by Disqus