正如你从标题中看到的那样,我想把单词中的小写字母改为大写字母,反之亦然,而且我需要使用结构体对象(在我的情况下),我有一个问题,当我把小写字母改为大写字母时,它只在第一个单词中改变,而不是在第二个,第三个等。我还从文件中读取单词
以下是输入文件
Aayak Audi
Ahmed Golf7
Samed Golf5
以下是代码
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
struct pismaStr
{
string ime;
string objekat;
};
void malaVelikaSlova (string name)
{
for (int i = 0; i < name.length()-1; i++)
{
if (name.at(i) >= 'A' && name.at(i) <= 'Z')
name.at(i) += 32;
else if (name.at(i) >= 'a' && name.at(i) <= 'z')
name.at(i) -= 32;
cout << name;
break;
}
}
int main()
{
ifstream pismo;
pismo.open("pismo.txt");
ofstream novoPismo;
novoPismo.open("novaSlova.txt");
pismaStr stvari[200];
int brojStvari = 0;
while(pismo >> stvari[brojStvari].ime >> stvari[brojStvari].objekat)
{
brojStvari++;
}
for (int i = 0; i < brojStvari; i++)
{
vector <pismaStr> vec = {pismaStr{stvari[i].ime}};
for (auto obj : vec)
{
malaVelikaSlova (obj.ime);
}
}
这是输出。
aayak
ahmed
samed
它是。
Aayak
ahmed
samed
我希望它看起来像这样
aAYAK
sAMED
aHMED
我怎么能解决这个问题呢?
但这将是一个问题,这条线是
for (int i = 0; i < name.length()-1; i++)
这将从 name[0]
到 name[name.length() - 2]
. 该 std::string::length
返回可用字符的数量。它不包括空结束符,所以你不需要减去1。它应该是
for (int i = 0; i < name.length(); i++)
是 break
语句的结尾处
for (int i = 0; i < name.length()-1; i++)
{
if (name.at(i) >= 'A' && name.at(i) <= 'Z')
name.at(i) += 32;
else if (name.at(i) >= 'a' && name.at(i) <= 'z')
name.at(i) -= 32;
cout << name;
break; // <--- this exits the loop entirely
}
您的 break;
告诉程序立即退出循环。不再执行循环的进一步迭代。您的 cout
语句也在循环中。一旦你真的让循环运行每一次迭代,你就会输出每一步的转换。为了只输出一次(在最后),你把它放在循环之外。如果你想对每个字符进行循环(你做到了),你的最终代码看起来像这样
void malaVelikaSlova (string name)
{
for (int i = 0; i < name.length() - 1; i++)
{
if (name.at(i) >= 'A' && name.at(i) <= 'Z')
name.at(i) += 32;
else if (name.at(i) >= 'a' && name.at(i) <= 'z')
name.at(i) -= 32;
}
cout << name;
}
你不需要对你的产品进行边界检查。string
索引,因为你是基于 string
长度,而且它不会改变,所以你不需要额外的开销。std::string::at
. 你可以直接使用索引操作符。
// name.at(i); // <-- no need to do this anywhere
name[i] // <-- slightly faster
因为你要对容器(字符串)中的每个元素(字符)进行一些操作,所以这是一个很好的候选方案。std::transform
,来自 <algorithm>
库。我在这里还用了一个lambda表达式,这是一个伟大的太从C++熟悉。
https:/en.cppreference.comwcppalgorithmtransform https:/en.cppreference.comwcpplanguagelambda。
void malaVelikaSlova (string name)
{
std::transform(
name.begin(),
name.end(),
[](char c) -> char
{
if (c >= 'A' && c <= 'Z')
return c + 32;
if (c >= 'a' && c <= 'z')
return c - 32;
return c; // <-- for all other characters
}
);
std::cout << name << "\n";
}
你甚至可以利用 std::isupper
, std::islower
, std::toupper
和 std::tolower
函数来使你的代码更加明确。注意 std::string
的别称。std::basic_string<char>
(其价值类型为 char
)、 upper
和 lower
功能运行于 unsigned char
s,所以你需要将这些数据转换为 char
至 unsigned char
s:
https:/en.cppreference.comwcppstringbasic_string。 https:/en.cppreference.comwcppstringbytetolower。 https:/en.cppreference.comwcppstringbytetoupper。 https:/en.cppreference.comwcppstringbyteisupper。 https:/en.cppreference.comwcppstringbyteislower。
void malaVelikaSlova (string name)
{
std::transform(
name.begin(),
name.end(),
[](unsigned char c) -> unsigned char // <-- must convert to unsigned to be safe with upper/lower functions
{
if std::isupper(c) return std::tolower(c);
if std::islower(c) return std::toupper(c);
return c; // <-- for all other characters
}
);
std::cout << name << "\n";
}