C++:字符串格式化
C++: String formatting
这是我的输入字符串:Muhammad Ali 65445519 76 butterfly123
这是我想要的输出:Muhammad Ali xxx-xx-xxx 76 xxxxxxxxx
注意:除了社会安全号码 (65445519) 之外,其他所有内容的长度都可能不同,即姓名、用户 ID (76) 和密码 (butterfly123)。
示例:
科比·布莱恩特 34567890 548 56 曼巴
我试过了,但我有一个长度为 2 的固定用户 ID。谁能想出一个用户 ID 也可以变化的解决方案?还是一种全新的不同方法?我不想使用字符串流,其中你一个一个地输入,然后分别处理字符串。然而,一个有效且短的字符串流解决方案将受到赞赏。谢谢
string s;
int j;
getline(cin,s);
for (int i=0; i<s.length(); i++)
{
if(s.at(i)=='0' || s.at(i)=='1' || s.at(i)=='2'
|| s.at(i)=='3' || s.at(i)=='4' || s.at(i)=='5'
|| s.at(i)=='6' || s.at(i)=='7' || s.at(i)=='8'
|| s.at(i)=='9')
{
s.replace(i,8,"xxxxxxxx");
s.insert(i+3,"-");
s.insert(i+6,"-");
j=i+14;
break;
}
}
for(j;j<s.length();j++)
{
s.replace(j,1,"x");
}
cout<<s<<endl;
是的,你应该尝试不同的方法。
考虑以下输入
Sam123456789 FarkenParker 221778833 46 foobar
您的方法最终会将“123456789”替换为 X-s,这显然是错误的。
正确做法:
1) 将单个字符串拆分为以空格分隔的单词。使用适合您的 std::array<std::string, 4>
或 std::vector<std::string>
。
2) 只需相应地替换第 2 个和第 5 个单词即可。
3) 然后将所有内容重新组合成一个字符串。
你不一定要用getline(cin,s);
,你可以把数据读入单独的变量中:
std::string name, surname, password;
unsigned long long security, ID;
std::cin >> name >> surname >> security >> ID >> password;
std::string processed_security, processed_pwd(password.size(), 'x');
while (security) processed_security += "x", security /= 10;
std::cout << name << surname << processed_security << ID << processed_pwd << std::endl;
关于这段代码的一些注释:
- 您可以为 ID 使用较小的无符号整数数据类型(例如
unsigned int
)
security
应该保存在可以容纳非常大数字的数据类型中,例如unsigned long long
- Docs for the
std::string
constructors used
为什么不使用名称、ID、密码...创建一个新的 class 并覆盖“>>”运算符?
并创建 "xxxxxxxxxx" 使用字符串构造函数 :
string word(oldword.size(), 'x');
oldword.size() 是单词的长度,'x' 是将填充整个字符串的字符
这是我的输入字符串:Muhammad Ali 65445519 76 butterfly123
这是我想要的输出:Muhammad Ali xxx-xx-xxx 76 xxxxxxxxx
注意:除了社会安全号码 (65445519) 之外,其他所有内容的长度都可能不同,即姓名、用户 ID (76) 和密码 (butterfly123)。
示例:
科比·布莱恩特 34567890 548 56 曼巴
我试过了,但我有一个长度为 2 的固定用户 ID。谁能想出一个用户 ID 也可以变化的解决方案?还是一种全新的不同方法?我不想使用字符串流,其中你一个一个地输入,然后分别处理字符串。然而,一个有效且短的字符串流解决方案将受到赞赏。谢谢
string s;
int j;
getline(cin,s);
for (int i=0; i<s.length(); i++)
{
if(s.at(i)=='0' || s.at(i)=='1' || s.at(i)=='2'
|| s.at(i)=='3' || s.at(i)=='4' || s.at(i)=='5'
|| s.at(i)=='6' || s.at(i)=='7' || s.at(i)=='8'
|| s.at(i)=='9')
{
s.replace(i,8,"xxxxxxxx");
s.insert(i+3,"-");
s.insert(i+6,"-");
j=i+14;
break;
}
}
for(j;j<s.length();j++)
{
s.replace(j,1,"x");
}
cout<<s<<endl;
是的,你应该尝试不同的方法。
考虑以下输入
Sam123456789 FarkenParker 221778833 46 foobar
您的方法最终会将“123456789”替换为 X-s,这显然是错误的。
正确做法:
1) 将单个字符串拆分为以空格分隔的单词。使用适合您的 std::array<std::string, 4>
或 std::vector<std::string>
。
2) 只需相应地替换第 2 个和第 5 个单词即可。
3) 然后将所有内容重新组合成一个字符串。
你不一定要用getline(cin,s);
,你可以把数据读入单独的变量中:
std::string name, surname, password;
unsigned long long security, ID;
std::cin >> name >> surname >> security >> ID >> password;
std::string processed_security, processed_pwd(password.size(), 'x');
while (security) processed_security += "x", security /= 10;
std::cout << name << surname << processed_security << ID << processed_pwd << std::endl;
关于这段代码的一些注释:
- 您可以为 ID 使用较小的无符号整数数据类型(例如
unsigned int
) security
应该保存在可以容纳非常大数字的数据类型中,例如unsigned long long
- Docs for the
std::string
constructors used
为什么不使用名称、ID、密码...创建一个新的 class 并覆盖“>>”运算符?
并创建 "xxxxxxxxxx" 使用字符串构造函数 :
string word(oldword.size(), 'x');
oldword.size() 是单词的长度,'x' 是将填充整个字符串的字符