设计题2、字符处理
设计函数,实现英文字符的大小写转换并去除其他字符。要求:字符串中的小写字符自动变换成对应的大写字符,而大写字符则变换成对应的小写字符。另,如果字符串中存在除英文大小写之外的字符请去除掉。
————————————————————这是我们课设中的一道题—————————————————————————
个人认为,大小写字母的转换还算简单,我能想到的方法是,用ASCII表,小写字母比大写字母大32,再利用循环和字符型数据的加减就可以解决啦。但是字符的删除就没那么简单。我开始的想法是令字符等于零,感觉上行得通,一下是我的源码。
#include<iostream>
using namespace std;
void convert(char a[]) //定义转换函数
{
int i;
for (i = 0; a[i]; i++)
{
if (a[i] >= 'a'&&a[i] <= 'z')
a[i] -= 32; //小写字母比对应大写字母ASCII表上多32
else if (a[i] >= 'A'&&a[i] <= 'Z')
a[i] += 32;
else
a[i] = 0; //删除字符
}
for (i = 0; a[i]; i++)
cout << a[i];
}
int main()
{
char chstring[20];
cout << "Please input a string:" << endl;
cin >> chstring;
convert(chstring);
system("pause");
return 0;
}
可是...运行结果是酱紫的:
可以发现数字是被删除了没错,可是数字后面的东西也没有了,就像是字符串到这路就结束了,所以删除字符并不是简单地将零赋值给字符。原因是:ASCII值为0的字符对应的是空字符\0,它的意义是“字符串结束符”,字符串遇到第一个\0就会认为该字符串到此结束。SO...需要改进。
最简单的解决方法是:扫描字符串中的字符,每当遇到需要删除的字符时,当前字符后的所有字符从前到后向前移动一位。以下是改动后的源码:
#include<iostream>
using namespace std;
void convert(char a[]) //定义转换函数
{
int i, j;
for (i = 0, j = 0; a[i] != 0; i++, j++)
{
if (a[j] >= 'a'&&a[j] <= 'z')
{
a[j] -= 32; //小写字母比对应大写字母ASCII表上多32
a[i] = a[j];
}
else if (a[j] >= 'A'&&a[j] <= 'Z')
{
a[j] += 32;
a[i] = a[j];
}
else
{
i--;
}
}
cout << a;
}
int main()
{
char chstring[20];
cout << "Please input a string:" << endl;
cin >> chstring;
convert(chstring);
system("pause");
return 0;
}
我又添加了一个循环变量j,相当于构建了一个“隐字符数组”,a[j]是隐的,用它来给a[i]的元素赋值,当遇到字母元素时a[j]变换大小写赋值给a[i],当遇到非字母元素时,i减一前移并不赋值,这样就达到了不输出非字母字符的效果。但是运行结果还是存在问题的:
可以看到,生成的字符串达到了题设中的两个要求,但是似乎它始终恪守着要与原字符串长度统一的原则,在正常生成的字符串后面会随机带上几个字母以补充因删除了数字而留下的空位,这是我们不想要的。我有思考过可否考虑只输出前几个字符或是在应该生成的字符串后面加上字符串结束符,可是试了半天未能如愿...哎有闲心了再慢慢试吧,再加上这个用字符数组方法太"C-style"了,所以我为了能不再纠结把题做出来改用string了...源码如下:
#include<iostream>
#include<string>
using namespace std;
void convert(string str) //定义转换函数
{
int i;
for (i = 0; i < str.length(); i++)
{
if (str[i] >= 'a' && str[i] <= 'z') //大小写转换
str[i] -= 32;
else if (str[i] >= 'A' && str[i] <= 'Z')
str[i] += 32;
}
string::iterator t = str.begin(); //得到指向字符串开头的Iterator
while (t != str.end())
{
if (*t >= '0' && *t <= '9')
{
str.erase(t); //string的erase函数可以删除指定字符
}
else
t++;
}
cout << str;
}
void convert(string str); //声明
int main()
{
string a;
cout << "Please input a string:" << endl;
cin >> a;
convert(a);
system("pause");
return 0;
}
天啊用string实在是太方便了......根本不用考虑咋循环咋设置循环变量,只需要string中的几个函数和一个迭代器的东西就可以解决了。iterator迭代器相当于指针,同时又比指针好用得多。可见c++中的string使c++相较于c处理字符的能力要强大了许多!下面是运行结果,美滋滋: