所以我还是C ++的新手,我正在尝试制作一个程序,让用户输入一个字符串,然后我的函数以相反的大小写返回字符串,所有字母均小写,然后全部大写。相反,我只是一直收到字符串的第一个字母,总是大写。不知道我在做什么错。有什么建议吗?
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
char answer[255] = "";
int max = strlen(answer);
void reverse() {
for (int i = 0; i < max; i++) {
if (islower(answer[i])) {
isupper(answer[i]);
}
else if (isupper(answer[i])) {
islower(answer[i]);
}
else if (isspace(answer[i])) {
isspace(answer[i]);
}
}
cout << answer[max];
}
void lower() {
for (int i = 0; i < max; i++) {
if (isupper(answer[i])) {
islower(answer[i]);
}
else {
answer[i] = answer[i];
}
}
cout << answer[max];
}
void upper() {
for (int i = 0; i < max; i++) {
if (islower(answer[i])) {
isupper(answer[i]);
}
else {
answer[i] = answer[i];
}
}
cout << answer[max];
}
int main() {
cout << "Please enter a word, or a series of words: " << endl;
cin >> answer[max];
reverse();
lower();
upper();
system("pause");
return 0;
}
答案 0 :(得分:0)
islower(char)
只是一个内置功能,用于检查 char
是否小写。 isupper
也是如此。字符的大小写不变。
要转换为小写/大写,请使用tolower
/ toupper
。这将在转换后的情况下返回字符。但是,重要的是您需要将返回值分配给角色本身。
有关islower
,isupper
,tolower
和toupper
的更多说明,请参见this answer。
“ cin >> answer [max];将只读取一个字符,因为answer [max]只是一个字符,第一个字符。在C ++中,您必须按顺序进行操作。例如,int max = strlen(answer);将根据当时字符串中的内容提供答案。由于该字符串早于一行的初始化且包含一个空字符串,因此max为0。“
因此,您的cin
应该是cin >> answer
。 但,它将接受您句子中的第一个单词。为了接受包括空格在内的所有单词,请改用getline()
。为了使用它,answer
应该声明为string answer
而不是char数组。
这是您接受完整句子的方式:getline(cin,answer);
max
在一些编译器中会因为模棱两可而出现错误。这是因为using namespace std;
。为避免这种情况,请将max
重命名为其他名称,例如maxlen
。 answer
的长度:最好是在接受用户的字符串后调用answer.length()
,而不是全局执行。您的工作代码应如下所示:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
string answer;
int maxlen;
void reverse() {
for (int i = 0; i < maxlen; i++) {
if (islower(answer[i])) {
answer[i] = toupper(answer[i]);
}
else if (isupper(answer[i])) {
answer[i] = tolower(answer[i]);
}
else if (isspace(answer[i])) {
answer[i]=' ';
}
}
cout << "Reversed string: " + answer << endl;
}
void lower() {
for (int i = 0; i < maxlen; i++) {
if (isupper(answer[i])) {
answer[i] = tolower(answer[i]);
}
else {
answer[i] = answer[i];
}
}
cout << "Lower case string: " + answer << endl;
}
void upper() {
for (int i = 0; i < maxlen; i++) {
if (islower(answer[i])) {
answer[i] = toupper(answer[i]);
}
else {
answer[i] = answer[i];
}
}
cout << "Upper case string: " + answer << endl;
}
int main() {
cout << "Please enter a word, or a series of words: " << endl;
getline(cin,answer);
cout << "Original string: " + answer << endl;
maxlen = answer.length();
reverse();
lower();
upper();
return 0;
}
输出:
Please enter a word, or a series of words: ReVeRsAl UPPER aNd lower Original string: ReVeRsAl UPPER aNd lower Reversed string: rEvErSaL upper AnD LOWER Lower case string: reversal upper and lower Upper case string: REVERSAL UPPER AND LOWER
答案 1 :(得分:0)
cin >> answer[max];
将只读取一个字符,因为answer[max]
恰好是一个字符,即数组中位置max
处的字符。
max
为0,因为您必须按顺序进行操作。例如,
int max = strlen(answer);
将在到达此行时提供answer
的长度。由于该字符串早已初始化了一行
char answer[255] = "";
并包含一个空字符串,max
将为0。这意味着answer[max]
为answer[0]
代码中的任何内容都不会更改max
,因此它将保持为0。 / p>
好的,假设我们稍作改动,而不是读成一个字符,而是读成一个字符串answer
。您将需要
cin.getline(answer, sizeof(answer));
因为
cin >> answer;
将读取一个以空格分隔的令牌。一个词。您陈述的目标是阅读多个单词。 istream::getline
会将在第一个参数中找到的所有内容读到行尾,或者在第二个参数中找到的字符数减去1(以为字符串的空终止符保留空间)。 sizeof(answer)
实际上是answer
数组的大小,以字节为单位。我们使用字节大小的字符进行操作,因此字符数和字节数相同。如果使用多字节字符,则必须格外小心。
这似乎是推荐使用std::string
和std::getline
的好地方。它们会带来很多问题,例如在大多数情况下无法读取的最大字符数。
我不会在这里使用它们,因为该分配可能具有“无string
s”政策。
因此,既然我们已经cin.getline(answer, sizeof(answer));
读取了用户的输入,我们就可以获取max
的大小。我们可以strlen
,但也可以使用istream::gcount
来获取getline
读取的字符数。
main
现在看起来像
int main() {
cout << "Please enter a word, or a series of words: " << endl;
cin.getline(answer, sizeof(answer));
max = cin.gcount();
reverse();
lower();
upper();
system("pause");
return 0;
}
此时,整堆东西都可能出错。
using namespace std;
可能会对max
造成严重破坏,因为可能与std::max
发生冲突。通常,避免using namespace std;
可以节省您经常键入的几个字母,而这可以避免浪费在调试它可能引起的奇怪错误上。
isupper(answer[i]);
并没有像其他人在评论中指出的那样有用。您要
answer[i] = toupper(static_cast<unsigned char>(answer[i]));
请参阅Do I need to cast to unsigned char before calling toupper(), tolower(), et al.?,以了解为何可能需要疯狂而毫无意义的演员表。谢谢HolyBlackCat引起我的注意。
之类的自我分配
answer[i] = answer[i];
毫无意义,因为一旦您停下来想一想,原因就会很明显。
类似
else if (isspace(answer[i])) {
isspace(answer[i]);
}
可能不是特别有用。如果answer[i]
是空格,将其设置为空格吗?已经是一个空间了。它将用空格替换其他形式的空格,制表符和回车符。换行符已被getline
选中。还可能需要与上述toupper
示例中使用的转换类似的转换。我仍在阅读。
如上所述,
cout << answer[max];
无效。它输出一个字符,如果max
已被修复,则answer[max]
将是终止的null。而是打印出整个数组。
cout << answer;
一般建议:
不要一次写太多代码。在编译和测试之前,写几行,最多一个函数。如果您已经测试过
int main() {
cout << "Please enter a word, or a series of words: " << endl;
cin >> answer[max];
cout << answer;
}
您将立即看到未正确读取数据。并在继续之前修复它。通过允许错误累积,您将很难发现任何一个错误。您可能正确地修复了一个错误,只是找到了被另一个错误撤消或隐藏的修复程序。
避免使用全局变量。尝试将变量放在尽可能小的范围内。在这种情况下,将answer
和max
移至main
并将它们作为参数传递给其他函数。这使得跟踪谁设置什么变量以及何时设置变得容易得多。它还有助于防止意外的Variable Shadowing。