Reputation: 25
I wrote this code for converting string to sentence case but i don't know where is the problem
for (int i = 0; s[i] != '\0'; i++)
{
if (i == 0 && s[i] >= 'a' && s[i] <= 'z')
{
s[i] -= 32;
cout << s[i];
}
else if (s[i] == '.')
{
if (s[i+1] == ' ')
{
if (s[i + 2] >= 'a' && s[i + 2] <= 'z')
{
s[i + 2] -= 32;
cout << s[i + 2];
}
}
else
{
if (s[i + 1] >= 'a' && s[i] <= 'z')
{
s[i + 1] -= 32;
cout << s[i + 1];
}
}
}
cout << s[i];
}
the problem is for example if i give the
video provides a powerful way to help you prove your point. when you click online video, you can paste in the embed code for the video you want to add. you can also type a keyword to search online for the video that best fits your document. to make your document look professionally produced, word provides header, footer, cover page, and text box designs that complement each other. for example, you can add a matching cover page, header, and sidebar.
the output is like this
VVideo provides a powerful way to help you prove your pointW. When you click online video, you can paste in the embed code for the video you want to addY. You can also type a keyword to search online for the video that best fits your documentT. To make your document look professionally produced, word provides header, footer, cover page, and text box designs that complement each otherF. For example, you can add a matching cover page, header, and sidebar.video provides a powerful way to help you prove your point. when you click online video, you can paste in the embed code for the video you want to add. you can also type a keyword to search online for the video that best fits your document. to make your document look professionally produced, word provides header, footer, cover page, and text box designs that complement each other. for example, you can add a matching cover page, header, and sidebar.
so basically one time it print the first letter of each sentence before dot and then upper case the first letter of sentence and after that repeats the input
Upvotes: 0
Views: 1202
Reputation: 1941
Here is another solution, I think it is more readable. It also uses a lambda with capture and STL algorithm.
#include <string>
#include <algorithm>
// returning function
std::string make_sentence(std::string const &str) {
std::string ans;
ans.reserve(str.size()); // we already know the size of the answer - optomization to allocate only once
bool search{true}; // our state variable - initially true
// we use std::back_inserter to populate our answer string
std::transform(std::begin(str), std::end(str), std::back_inserter(ans),
[search] (auto &s) mutable // note the mutable here, by default captured search is const
{
// s is a char
if (s == ' ') return s;
if (s == '.') {
search = true; // change state to true after dot
return s;
}
if (search) {
// if we were searching for the start of a sentence
search = false; // stop search
// use either of this return statements, but in real-life beware encodings. String manipulation is pain.
return std::toupper(s, std::locale());
//return static_cast<char>(std::toupper(s));
}
return s;
});
return ans;
}
// modifying function
void make_sentence2(std::string &str) {
bool search{true}; // our state variable - initially true
// we use the same iterator std::begin(str) to modify the same string - it is safe to do so since we do not invalidate iterators
std::transform(std::begin(str), std::end(str), std::begin(str),
[search] (auto &s) mutable // note the mutable here, by default captured search is const
{
// s is a char
if (s == ' ') return s;
if (s == '.') {
search = true; // change state to true after dot
return s;
}
if (search) {
// if we were searching for the start of a sentence
search = false; // stop search
return std::toupper(s, std::locale());
}
return s;
});
}
int main() {
const std::string str = "video provides a powerful way to help you prove your point. when you click online video, you can paste in the embed code for the video you want to add. you can also type a keyword to search online for the video that best fits your document. to make your document look professionally produced, word provides header, footer, cover page, and text box designs that complement each other. for example, you can add a matching cover page, header, and sidebar.";
auto str2{str}
auto ans = make_sentence(str);
make_sentence2(str2);
std::cout << ans << '\n;
std::cout << str2 << '\n';
return 0;
}
Upvotes: 1
Reputation: 1187
Just comment out or remove two lines(becuase they are generating that extra character) and the code will work as you want :
cout << s[i + 2];
and
cout << s[i + 1];
Here's is the example for the same :
for (int i = 0; s[i] != '\0'; i++)
{
if (i == 0 && s[i] >= 'a' && s[i] <= 'z')
{
s[i] -= 32;
cout << s[i];
i++;
}
else if (s[i] == '.')
{
if (s[i+1] == ' ')
{
if (s[i + 2] >= 'a' && s[i + 2] <= 'z')
{
s[i + 2] -= 32;
// cout << s[i + 2];
}
}
else
{
if (s[i + 1] >= 'a' && s[i] <= 'z')
{
s[i + 1] -= 32;
//cout << s[i + 1];
}
}
}
cout << s[i];
}
Upvotes: 1
Reputation: 1175
I think you are over thinking it. You should have a flag for start of sentence and set it to true to start. Then after displaying the letter in upper case reset the flag.
void tosentence(const char *s)
{
auto startsentense = true;
for (auto i = 0; s[i]; i++)
{
if (startsentense && isalnum(s[i]))
{
std::cout << static_cast<char>(toupper(s[i]));
startsentense = false;
}
else if (s[i] == '.')
{
std::cout << s[i];
startsentense = true;
}
else
{
std::cout << s[i];
}
}
}
Upvotes: 1