新版 2018/7/3更新
直接使用transform函数,第四个参数使用lambda表达式即可
代码如下:
transform(word.begin(),word.end(),new_word.begin(),[](char c)->char { return toupper(c);});
这样就行了。变量word是旧字符串,new_word是新字符串。
旧版
C++中没有提供对string串进行直接大小写转换的函数,只能采用toupper & tolower函数对单个字符进行转换;
可以使用STL中的algorithm头文件中函数实现;
< algorithm > : transform函数
transform参数如下:
/*////////////////////////////////
template < class InputIterator, class OutputIterator, class UnaryOperator >
OutputIterator transform ( InputIterator first1, // 源容器的起始地址
InputIterator last1, // 源容器的终止地址
OutputIterator result, // 目标容器的起始地址
UnaryOperator op ); // 函数指针
// typedef 目标容器元素类型 (*UnaryOperator)(源容器元素类型);
template < class InputIterator1, class InputIterator2,
class OutputIterator, class BinaryOperator >
OutputIterator transform ( InputIterator1 first1, // 源容器1的起始地址
InputIterator1 last1, // 源容器1的终止地址
InputIterator2 first2, // 源容器2的起始地址,元素个数与1相同
OutputIterator result, // 目标容器的起始地址,元素个数与1相同
BinaryOperator binary_op ); // 函数指针
// typedef 目标容器元素类型 (*BinaryOperator)(源容器1元素类型,源容器2元素类型);
//*////////////////////////////////
注意:(错误演示)
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string word;
cin>>word;
transform(word.begin(), word.end(), word.begin(), toupper);//转换成大写
cout<<word<<endl;
return 0;
}
但在使用g++编译时会报错:
提示:对 transform的调用没有匹配的函数。
这里出现错误的原因是Linux将toupper实现为一个宏而不是函数:
/usr/lib/syslinux/com32/include/ctype.h:
/* Note: this is decimal, not hex, to avoid accidental promotion to unsigned */
#define _toupper(__c) ((__c) & ~32)
#define _tolower(__c) ((__c) | 32)
__ctype_inline int toupper(int __c)
{
return islower(__c) ? _toupper(__c) : __c;
}
__ctype_inline int tolower(int __c)
{
return isupper(__c) ? _tolower(__c) : __c;
}
可以看到,在Linux的g++编译器中,将tolower设置为一个宏,并不是一个函数,何谈函数指针呢,所以参数4不可以直接使用tolower和toupper;
具体实现如下:
方法一:
#include <iostream>
#include<unordered_map>
#include<set>
#include<string>
#include<algorithm>
using namespace std;
/*统计输入字符串中的特定单词的个数
或者统计除特定单词之外的个数(忽略标点符号)
忽略大小写(转换成小写)
*/
/** transform(word.begin(),word.end(),t_word.begin(),to_lower)
*
* \param 1: 源容器的起始地址
* \param 2:源容器的终止地址
* \param 3: 目标容器的起始地址,容器大小和源容器相同,resize()重新设置
* \param 4: 函数指针
* \return :none
* \notice: 第四个参数一定要是个函数指针,不能为tolower;要自己定义函数
这里出现错误的原因是Linux将toupper实现为一个宏而不是函数:/usr/lib/syslinux/com32/include/ctype.h:
*/
char to_lower(char c)
{
return tolower(c);
}
char to_upper(char c)
{
return toupper(c);
}
int main()
{
unordered_map<string,int> m;
set<string> s {"!",",",":"};//标点符号
string word;
string t_word;//转换成小写的Word
cin>>word;
while(word != "0")
{
t_word.resize(word.size());//!!!将t_word调整为和Word相同的大小;因为transform需要两个相同大小的string
transform(word.begin(),word.end(),t_word.begin(),to_lower);
if(s.find(t_word) == s.end())//find()返回一个迭代器,仅当Word在set中的时候,返回该元素的迭代器;否则,返回尾后迭代器。
{
m[t_word]++;
}
cin>>word;
}
for(auto it=m.begin(); it != m.end(); ++it)
{
cout<<it->first<<" occurs "<<it->second << ((it->second >1) ? " times":" time" )<< endl;
}
return 0;
}
方法二:
另外,看到一个博主有另一种方法,在这里也贴出来:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <cctype>
using namespace std;
int main()
{
string src = "Hello World!";
string dst;
transform(src.begin(), src.end(), back_inserter(dst), ::toupper);
cout << dst << endl;
transform(src.begin(), src.end(), dst.begin(), ::tolower);
cout << dst << endl;
return 0;
}
使用了back_inserter;
本文参考了:
http://www.cnblogs.com/KeenLeung/archive/2013/03/17/2965192.html
http://blog.youkuaiyun.com/loushuai/article/details/51289345