除引号外,删除字符串中的空格,转换大小写
Remove whitespace, convert case, in string except in quotes
我使用的是没有Boost的c++ 03。
假设我有一个字符串,如…日期为"星期一"
我想把它处理成
THEDAYISMon天也就是说,将不在引号内的内容转换为大写,并删除不在引号内的空白。
字符串可以不包含引号,但如果包含引号,则只有2个。
我尝试使用STL算法,但我卡住了如何记住它是否在元素之间的引号。
当然我可以用老式的for循环来实现,但我想知道是否有一种奇特的c++方法。
谢谢。
这就是我使用for循环的结果
while (getline(is, str))
{
// remove whitespace and convert case except in quotes
temp.clear();
bool bInQuote = false;
for (string::const_iterator it = str.begin(), end_it = str.end(); it != end_it; ++it)
{
char c = *it;
if (c == '"')
{
bInQuote = (! bInQuote);
}
else
{
if (! ::isspace(c))
{
temp.push_back(bInQuote ? c : ::toupper(c));
}
}
}
swap(str, temp);
您可以使用STL算法做如下操作:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
struct convert {
void operator()(char& c) { c = toupper((unsigned char)c); }
};
bool isSpace(char c)
{
return std::isspace(c);
}
int main() {
string input = "The day is "Mon Day" You know";
cout << "original string: " << input <<endl;
unsigned int firstQuote = input.find(""");
unsigned int secondQuote = input.find_last_of(""");
string firstPart="";
string secondPart="";
string quotePart="";
if (firstQuote != string::npos)
{
firstPart = input.substr(0,firstQuote);
if (secondQuote != string::npos)
{
secondPart = input.substr(secondQuote+1);
quotePart = input.substr(firstQuote+1, secondQuote-firstQuote-1);
//drop those quotes
}
std::for_each(firstPart.begin(), firstPart.end(), convert());
firstPart.erase(remove_if(firstPart.begin(),
firstPart.end(), isSpace),firstPart.end());
std::for_each(secondPart.begin(), secondPart.end(), convert());
secondPart.erase(remove_if(secondPart.begin(),
secondPart.end(), isSpace),secondPart.end());
input = firstPart + quotePart + secondPart;
}
else //does not contains quote
{
std::for_each(input.begin(), input.end(), convert());
input.erase(remove_if(input.begin(),
input.end(), isSpace),input.end());
}
cout << "transformed string: " << input << endl;
return 0;
}
输出如下:
original string: The day is "Mon Day" You know
transformed string: THEDAYISMon DayYOUKNOW
使用您所显示的测试用例:
original string: The day is "Mon Day"
transformed string: THEDAYISMon Day
只是为了搞笑,使用自定义迭代器,std::copy
和std::back_insert_iterator
,以及知道跳过空白并在引号字符上设置标志的operator++
:
CustomStringIt& CustomStringIt::operator++ ()
{
if(index_<originalString_.size())
++index_;
if(!inQuotes_ && isspace(originalString_[index_]))
return ++(*this);
if('"'==originalString_[index_])
{
inQuotes_ = !inQuotes_;
return ++(*this);
}
return *this;
}
char CustomStringIt::operator* () const
{
char c = originalString_[index_];
return inQuotes_ ? c : std::toupper(c) ;
}
您可以使用stringstream
和getline
与"
字符作为分隔符,而不是换行符。将字符串分成三种情况:第一个引号之前的部分,引号中的部分,第二个引号之后的部分。
在添加到输出之前处理第一部分和第三部分,但添加第二部分时不进行处理。
如果字符串不包含引号,则整个字符串将包含在第一部分中。第二部分和第三部分将为空。
while (getline (is, str)) {
string processed;
stringstream line(str);
string beforeFirstQuote;
string inQuotes;
getline(line, beforeFirstQuote, '"');
Process(beforeFirstQuote, processed);
getline(line, inQuotes, '"');
processed += inQuotes;
getline(line, afterSecondQuote, '"');
Process(afterFirstQuote, processed);
}
void Process(const string& input, string& output) {
for (string::const_iterator it = input.begin(), end_it = input.end(); it != end_it; ++it)
{
char c = *it;
if (! ::isspace(c))
{
output.push_back(::toupper(c));
}
}
}
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 2D数组来自文本输入,中间有空格
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- C++ - 如何将空格键转换为短划线以进行cmd输入
- C++:将带有空格的cin转换为不带getline函数的字符串
- 如何将包含空格和数字的句子从大写转换为小写
- 将有符号的 Int 转换为带空格的十六进制字符串
- 将字符串转换为char,空格字符未正确转换
- 在c++中将字符串转换为不带空格的字符数组
- 除引号外,删除字符串中的空格,转换大小写
- 使用std::stringstream转换为字符串在空格处失败