在学C++,尝试着做C++primer中这样一道题:使用迭代器将 string 对象中的字符都改为大写字母。
结果输出的总是修改之前的小写字母,解决过程:
1、先怀疑string里面的某个字母是否可替换,小测了一把
string s("hello world");
s[2] = 'L';
cout << s << endl;
验证是可以替换成功的。
2、怀疑下标索引直接s[i] -= 32; 是否有效,(在断点情况下,s[i]却是个错误的表达式,很奇怪,s和i单独输出都ok),于是把下标访问改成iterator访问(新手总是这样小白),结果证明不是这个问题。
3、怀疑字母替换后string地址在内存内是否发生变化,于是打出转换前的vector所有元素地址,和转换中的string s的地址,发现端倪,原来写
string s = *iter;
s并不是引用类型,而是创建了一份拷贝。加上&,运行测试,成了。
本来这篇文章没有什么价值,只为了以后有个记录的习惯。之前写测试代码写完就删,后面记忆模糊的时候想看都没得看了。养成记录好习惯的开头吧。
// Pracitce.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <list>
#include <deque>
#include <vector>
using namespace std;
template<class T>
void print(T &obj)
{
T::iterator iter = obj.begin();
cout << "\n---------------------------输出容器---------------------------\n" << endl;
while(iter != obj.end())
{
cout << *iter << "\t";
++iter;
}
cout << endl;
}
template<class T>
void toUper(T &t)
{
T::iterator iter = t.begin();
while(iter != t.end())
{
string &s = *iter;//原来写成:string s = *iter; 导致s生成的是副本
//cout << &s << endl;
for (string::iterator iterS = s.begin(); iterS != s.end(); iterS++)
{
if (*iterS >= 'a' && *iterS <= 'z')
{
//cout << *iterS << " ";
*iterS -= 32;
//cout << *iterS << " ";
}
}
//cout << &s << endl;
iter ++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char *str[] = {"hello","world","mynameis", "hlw"};
vector<string> vec(str,str + sizeof(str)/sizeof(str[0]));
/*for (int i = 0; i < vec.size(); i ++)
{
cout << &vec[i] << '\t';
}*/
print(vec);
toUper(vec);
print(vec);
/*string s("hello world");
s[2] = 'L';
cout << s << endl;*/
system("pause");
return 0;
}