stringstream、getline的用法


计算一系列数的和

这段代码假设输入是格式良好的,即每行都包含至少一个整数,并且整数之间由空格分隔
输入例子:
1 2 3
4 5
0 0 0 0 0
输出例子:
6
9
0

#include <iostream>
#include <cstring>
#include <sstream>
using namespace std;

int main() {
    string line;    // 定义一个字符串line来存储从输入流中读取的每一行。
    // 使用while循环和getline函数从cin读取行到line中。这个循环会持续进行,直到输入流结束
    while (getline(cin, line)) {
        stringstream ss;    // 创建一个字符串流ss
        ss << line;         // 将读取到的行line放入字符串流ss中
        int res = 0, x;

        /*使用另一个while循环从字符串流ss中读取整数到变量x中,并将每个读取到的整数累加到res中。
        这个循环会持续进行,直到字符串流中没有更多的整数*/
        while (ss >> x) {
            /*
                当你从stringstream对象中使用输入操作符>>读取数据时,它会根据空格来分割字符串
                并将每个由空格分隔的部分作为一个独立的字符串或数字读取
            */
            res += x;
        }
        cout << res << endl;
    }
}


getline函数

getline 是一个在 C++ 标准库中非常有用的函数,它用于从输入流中读取一整行文本。getline 函数可以处理包含空格的字符串,这使得它在需要从输入中读取包含空格的整行文本时特别有用,这与 cin 运算符不同,后者在遇到空格、制表符或换行符时会停止读取。

getline 函数的原型通常如下:

istream& getline (istream& is, string& str, char delim);
  • istream& is:表示一个输入流,通常是 cin(标准输入)或者一个 ifstream 对象(用于从文件读取)。
  • string& str:这是一个字符串引用,getline 会把从输入流中读取的字符序列存储在这个字符串中。
  • char delim:这是一个可选参数,表示定界符(delimiter),即标志着输入结束的字符。如果不提供这个参数,getline 默认使用换行符(\n)作为定界符。

然而,在 <string> 头文件中,getline 的更常见形式是没有第三个参数的版本:

istream& getline (istream& is, string& str);

在这个版本中,getline 会读取输入直到遇到换行符,然后将读取的内容(不包括换行符)存储在 str 中。

下面是一个使用 getline 函数的简单示例:

#include <iostream>
#include <string>

int main() {
    std::string line;
    std::cout << "Please enter a line of text: ";
    std::getline(std::cin, line);
    std::cout << "You entered: " << line << std::endl;
    return 0;
}

在这个例子中,程序会等待用户输入一行文本,直到用户按下回车键(即输入换行符)。然后,程序会输出用户输入的内容。注意,getline 读取了整行,包括其中的空格,但不会包括换行符本身。



stringstream的常见用法

stringstream是C++标准库中的一个非常有用的类,它定义在<sstream>头文件中。stringstream类允许你方便地在字符串和各种数据类型之间进行转换和处理。它实际上是一个流,就像cincout一样,但它是在内存中操作的,而不是与外部设备(如控制台或文件)交互。

以下是stringstream的一些常见用法:

  1. 数据类型转换:你可以使用stringstream来轻松地将数字转换为字符串,或者将字符串解析为数字。例如:
#include <sstream>
#include <string>

int main() {
    std::stringstream ss;
    int a = 123;
    std::string str;

    // 将整数转换为字符串
    ss << a;
    ss >> str; // 或者使用 str = ss.str();

    // 将字符串转换为整数
    str = "456";
    ss.clear(); // 清除之前的错误状态
    ss.str(str); // 设置新的字符串内容
    int b;
    ss >> b; // 现在b包含整数456

    return 0;
}

注意:在实际使用中,你可能需要更严格地处理错误和边界情况。

  1. 字符串拼接和格式化:你可以使用stringstream来构建复杂的字符串,通过插入各种数据类型和格式化输出。例如:
#include <sstream>
#include <iostream>

int main() {
    std::stringstream ss;
    int age = 30;
    std::string name = "Alice";

    // 拼接字符串和整数
    ss << "My name is " << name << " and I am " << age << " years old.";

    // 输出结果
    std::cout << ss.str() << std::endl;

    return 0;
}
  1. 字符串分割:你可以使用stringstream来分割字符串,特别是当字符串由空格、逗号或其他分隔符分隔时。例如:
#include <sstream>
#include <vector>
#include <string>
#include <iostream>

int main() {
    std::string line = "apple orange banana";
    std::vector<std::string> words;
    std::stringstream ss(line);
    std::string word;

    // 分割字符串并存储单词
    while (ss >> word) {
        words.push_back(word);
    }

    // 输出分割后的单词
    for (const auto& w : words) {
        std::cout << w << std::endl;
    }

    return 0;
}
  1. 清空stringstream:如果你想重用同一个stringstream对象,你可以使用str("")clear()方法来清空内容和重置状态。例如:
ss.str(""); // 清空字符串内容
ss.clear(); // 重置错误状态标志

stringstream是一个功能强大的工具,它结合了字符串处理的灵活性和C++流操作的简便性。通过掌握这些常见用法,你可以在C++编程中更加高效地处理字符串和数据转换任务。



stringstream分割字符串的标志

在C++中,使用stringstream来分割字符串时,默认的分隔标志是空格。当你从stringstream对象中使用输入操作符>>读取数据时,它会根据空格来分割字符串,并将每个由空格分隔的部分作为一个独立的字符串或数字读取。

例如,如果你有一个包含空格的字符串,并且你想将其分割成多个部分,你可以这样做:

#include <sstream>
#include <iostream>
#include <string>

int main() {
    std::string str = "This is a test string";
    std::stringstream ss(str);
    std::string word;

    while (ss >> word) {
        std::cout << word << std::endl;
    }

    return 0;
}

在这个例子中,stringstream对象ss会根据空格将字符串"This is a test string"分割成多个单词,并且每次循环迭代时都会输出一个单词。

然而,如果你需要使用不同的分隔符来分割字符串,你可以使用std::getline()函数,并指定一个分隔符。但是,请注意,std::getline()函数不是直接与stringstream一起使用的;相反,它是与任何istream对象(包括stringstream)一起使用的。例如:

#include <sstream>
#include <iostream>
#include <string>

int main() {
    std::string str = "This,is,a,test,string";
    std::replace(str.begin(), str.end(), ',', ' '); // 将逗号替换为空格
    std::stringstream ss(str);
    std::string word;

    while (ss >> word) {
        std::cout << word << std::endl;
    }

    // 或者直接使用getline和指定的分隔符
    std::string str2 = "This,is,a,test,string";
    std::stringstream ss2(str2);
    std::string item;
    char delimiter = ',';

    while (std::getline(ss2, item, delimiter)) {
        std::cout << item << std::endl;
    }

    return 0;
}

在第二个例子中,我们首先使用std::replace()函数将字符串中的逗号替换为空格,然后像之前一样使用stringstream和输入操作符>>。但是,我们也展示了如何使用std::getline()函数直接从stringstream对象ss2中读取由逗号分隔的项。在这个情况下,delimiter变量被设置为逗号字符',',并且std::getline()会在遇到这个分隔符时停止读取。


字符串排序

输入描述:
输入有两行,第一行n
第二行是n个字符串,字符串之间用空格隔开

输出描述:
输出一行排序后的字符串,空格隔开,无结尾空格

示例1
输入例子:
5
c d a bb e
输出例子:
a bb c d e

#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <algorithm>
#include <limits>

using namespace std;

int main() {
    string line;
    stringstream ss;
    vector<string> res;
    int num;

    cin >> num; // 读取一个整数,尽管在后续代码中并未使用它
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略直到换行符的所有字符

    getline(cin, line); // 现在读取一整行,不包含之前的换行符
    ss << line; // 将读取的行放入 stringstream 中

    string tmp;
    // 从 stringstream 中读取单词并存储到 vector 中
    while (ss >> tmp) {
        res.push_back(tmp); // 或者使用 emplace_back(tmp);
    }

    sort(res.begin(), res.end()); // 对 vector 中的字符串进行排序

    // 输出排序后的结果
    for (const auto& str : res) {
        cout << str << " ";
    }
    cout << endl;

    return 0;
}


cin.ignore()

cin.ignore(); 是一个常用于C++输入流处理的函数,它用于从输入流中抽取并丢弃字符。这个函数通常用于在混合使用 >> 运算符和 getline() 函数进行输入时清除输入缓冲区中的不需要的字符,如换行符。

当你使用 cin >> someVariable; 读取输入时,它会读取直到遇到空白字符(空格、制表符或换行符)为止。但是,这个空白字符不会被从输入流中移除,而是留在那里等待下一次读取操作。如果你紧接着使用 getline() 读取一行,getline() 会立即看到那个换行符,并认为行已经结束,因此不会读取任何内容。

为了解决这个问题,你可以在 cin >> someVariable; 之后使用 cin.ignore(); 来丢弃换行符。但是,更健壮的做法是指定要忽略的字符数以及终止字符,以确保清除所有不需要的字符。例如:

cin >> num;
cin.ignore(numeric_limits<streamsize>::max(), '\n');

这里,numeric_limits<streamsize>::max() 表示要忽略的最大字符数,这实际上是设置了一个非常大的数,以确保忽略所有直到换行符 '\n' 的字符。但是,你需要包含 <limits> 头文件来使用 numeric_limits

posted @   guanyubo  阅读(280)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示