我需要每个单词的大写和其他小写,但函数convertFirstAndLastLetter只执行句子的第一个和最后一个。
void convertFirstAndLastLetter(char wrd[])
{
size_t last = strlen(wrd) - 1;
size_t first = 0;
wrd[first] = toupper(wrd[first]);
wrd[last] = toupper(wrd[last]);
for(int i = first + 1 ; i < last - 1; i++)
{
wrd[i] = tolower(wrd[i]);
}
}
int main ()
{
float val;
cout << "ent ";
cin >> val;
if (val == 4)
{
char wrd[256];
cin.ignore();
cin.getline(wrd,256);
convertFirstAndLastLetter(wrd);
cout << wrd;
return 0;
}
}
答案 0 :(得分:2)
现在你将一整行传递给你的函数,所以第一个和最后一个字符都是正在改变的。
要解决此问题,您需要将该行拆分为单词,这可以通过使用std::cin >> word
一次读取一个单词来完成,或者读取整行然后使用std::stringstream
将其拆分起来。两者大致相同,但我使用了字符串流。
接下来,如果我正确地阅读你的陈述,你希望每个单词的第一个和最后一个“字母”为大写,其余为小写。这意味着我们需要找到第一个和最后一个字母,以防在该字词之前或之后有标点符号。
确定第一个和最后一个后,很容易将它们大写并小写其余部分。
#include <iostream>
#include <string>
#include <sstream>
#include <cctype>
void convertFirstAndLastLetter(std::string& word)
{
if(!word.empty())
{
size_t first = 0;
size_t last = word.size() - 1;
//Find first alpha character
while(first < word.size() && !std::isalpha(word[first]))
{
++first;
}
//If the position is valid, uppercase it
if(first < word.size())
{
word[first] = static_cast<char>(std::toupper(word[first]));
}
//Find last alpha character
while(last > first && !std::isalpha(word[last]))
{
--last;
}
//If the position is valid, uppercase it
if(last > first)
{
word[last] = static_cast<char>(std::toupper(word[last]));
}
for(size_t i = first + 1; i < word.size() && i < last; ++i)
{
if(std::isalpha(word[i]))
{
word[i] = static_cast<char>(std::tolower(word[i]));
}
}
}
}
int main()
{
float val;
std::cout << "ent ";
std::cin >> val;
std::cin.ignore();
if(val == 4)
{
std::string line;
if(std::getline(std::cin, line))
{
std::string word;
std::stringstream ss(line);
while(ss >> word)
{
convertFirstAndLastLetter(word);
std::cout << word << " ";
}
std::cout << "\n";
}
}
return 0;
}
请记住,这将丢弃每行开头和结尾的任何额外空格以及单词之间的任何额外空格。我打印它们的方式也将在每行的末尾添加额外的空间。你没有在你的问题中提到任何关于这些事情的担忧,所以我并不担心它们。它们都可以通过一点额外的努力来解决。
答案 1 :(得分:2)
现在代码重复较少:
#include <algorithm>
#include <iostream>
#include <string>
template<typename It>
void upperFirstAlpha(It begin, It end)
{
auto first = std::find_if(begin, end, isalpha);
if (first != end)
*first = toupper(*first);
}
int main()
{
for (std::string s; std::cin >> s;) {
std::transform(s.begin(), s.end(), s.begin(), tolower);
upperFirstAlpha(s.begin(), s.end());
upperFirstAlpha(s.rbegin(), s.rend());
std::cout << s << ' ';
}
}
正如@Retired Ninja所指出的那样,第一个版本不会用于标点符号,这个版本是否适合您的输入取决于输入的内容。
答案 2 :(得分:1)
此功能
void convertFirstAndLastLetter(char wrd[])
{
size_t last = strlen(wrd) - 1;
size_t first = 0;
wrd[first] = toupper(wrd[first]);
wrd[last] = toupper(wrd[last]);
for(int i = first + 1 ; i < last - 1; i++)
{
wrd[i] = tolower(wrd[i]);
}
}
错了。例如,如果字符数组为空,它只有终止零,那么表达式strlen(wrd) - 1
将为类型为size_t
的对象提供最大值,并在下一个语句中
wrd[last] = toupper(wrd[last]);
您将尝试更改阵列之外的内存。
此外,如果您使用标准功能strlen
,则必须包含标题<cstring>
。
实际上没有必要使用函数strlen。代码可以写得更简单
#include <cctype>
//...
void convertFirstAndLastLetter( char wrd[] )
{
if ( *wrd )
{
*wrd = std::toupper( *wrd );
if ( *++wrd )
{
while ( *( wrd + 1 ) )
{
*wrd = std::tolower( *wrd );
++wrd;
}
*wrd = std::toupper( *wrd );
}
}
}
答案 3 :(得分:-1)
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
void convertFirstAndLastLetter(char wrd[])
{
size_t last = strlen(wrd) - 1;
size_t first = 0;
wrd[first] = toupper(wrd[first]);
wrd[last] = toupper(wrd[last]);
for(int i = first + 1 ; i < last; i++)
{
wrd[i] = tolower(wrd[i]);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
float val;
cout << "ent ";
cin >> val;
if (val == 4)
{
char wrd[256];
cin.ignore();
cin.getline(wrd,256);
convertFirstAndLastLetter(wrd);
cout << wrd;
return 0;
}
}