Reputation: 1
I'm a student and new to programming
I'm trying to make every first letter of every word uppercased and the rest lowercased.
The output currently is that only the first word is being printed even though I'm typing in 2 or more words.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int i;
char str[100];
char rev;
int len = 0;
cout << "Enter a string: ";
cin >> str;
len = strlen(str);
for (i = 0; i < len; i++)
{
if (i == 0)
{
str[i] = toupper(str[i]);
}
else
{
str[i] = tolower(str[i]);
}
cout << str[i];
}
}
Upvotes: 0
Views: 473
Reputation: 5503
As others have pointed out, once std::cin
encounters a space it will stop reading.
The code below is still reading 1 word at a time. I like how it essentially does a string split for you without much effort on your part.
I then use iterator
's to traverse the characters in the std::string
.
The skip
function was needed to remove any space in the stream
so that I could then check for a newline (\n
) character. If a newline character is detected, break
out of the loop.
static std::istream& skip( std::istream& stream )
{
static const std::set<char> needles{ ' ', '\t', '\r', '\v' };
while ( needles.find( static_cast<char>( stream.peek( ) ) ) != needles.end( ) )
{
stream.ignore( );
}
return stream;
}
int main( )
{
const auto to_upper{ [ ]( auto begin, auto end ) {
std::transform( begin, end, begin, [ ]( unsigned char c ) {
return std::toupper( c );
} );
} };
const auto to_lower{ [ ]( auto begin, auto end ) {
std::transform( begin, end, begin, [ ]( unsigned char c ) {
return std::tolower( c );
} );
} };
std::cout << "Enter a strings\n";
for( std::string input{ }; std::cin >> input; )
{
to_upper( input.begin( ), input.begin( ) + 1 );
to_lower( input.begin( ) + 1, input.end( ) );
std::cout << input << ' ';
if ( std::cin >> skip && std::cin.peek( ) == '\n' )
{
std::cout << '\n';
break;
}
}
}
Upvotes: 0
Reputation: 13076
Note your code still has more of a "c" flavor to it then a "c++" flavor. Managing the sizes of your own arrays and using indices can still be used, but its better left to classes of the standard library. So if you want a string then use std::string and not char str[100]; Also note that string has a length method and that converting a string to an array of characters is not needed. Have a look at this example:
#include <string>
#include <set>
#include <iostream>
// do not teach yourself to type : using namespace std.
// just type std:: in front of every std type
// it will avoid problems in bigger projects later
// for anything you do make a function with a readable name.
// pass by value so we get a copy of the string to work on.
std::string capitalize(std::string string)
{
// create a static set of unique characters that will
// be used to recognize where new words begin.
// I added a few, maybe more are needed.
static std::set<char> delimiters{ ' ', ',', '.', '\n' };
// first character of a sentence should always be uppercase
bool make_next_char_uppercase = true;
// loop over all the characters in the input string.
// this is called a range based for loop and is
// an improvement over the indexed for loop
// used since "C", this style of loop can't go outside
// the bounds of the array.
// use a reference so we can modify the characters in place
for (char& c : string)
{
if (make_next_char_uppercase) c = toupper(c);
// the next line of code is C++20 syntax.
// but it means that if you encounter a word delimiter
// then the next character read must be changed to uppercase.
make_next_char_uppercase = delimiters.contains(c);
// for earlier versions of C++ use
//make_next_char_uppercase = (std::find(delimiters.begin(), delimiters.end(), c) != delimiters.end());
}
return string;
}
int main()
{
auto output = capitalize("the quick brown fox jumps over the lazy dog!\nalso text after a newline and a,should be uppercase!");
std::cout << output;
}
Upvotes: 1
Reputation: 4663
std::cin
stop reading when it sees a space. If you want to read until a newline, use getline()
. Also, as in C++ use std::string
instead of C-style string. And you shouldn't use using namespace std;
as it's consider bad practise as show in here.
My "recommend" code:
#include <iostream>
#include <string>
#include <cctype>
int main()
{
std::string str;
char rev{};
std::cout << "Enter a string: ";
getline(std::cin, str);
int len {str.size()};
for (int i = 0; i < len; i++)
{
if (i == 0)
{
str[i] = toupper(str[i]);
}
if (str[i] == ' ')
{
str[i + 1] = toupper(str[i + 1]);
}
std::cout << str[i];
}
}
Upvotes: 0
Reputation: 1
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int i;
char str[100];
char rev;
int len = 0;
cout << "Enter a string: ";
cin.getline(str, 100);
len = strlen(str);
for (i = 0; i < len; i++)
{
if (i == 0)
{
str[i] = toupper(str[i]);
}
if (str[i] == ' ')
{
str[i + 1] = toupper(str[i + 1]);
}
cout << str[i];
}
}
Upvotes: 0