I have a string: "apple". How can I convert only the first character to uppercase and get a new string in the form of "Apple"?
I can also have a string with multibyte characters.
What if the first character of the string is a multibyte character ?
string str = "something";
str[0] = toupper(str[0]);
That's all you need to do. It also works for C strings.
Like what Carneigie said,
string str = "something";
str[0] = toupper(str[0]);
but also remember to:
#include <string>
#include <cctype>
all the way up
I cannot use str[0] because, I can have string which has multibyte characters
I don't know of any CRT implementation that supports non-ASCII character classification and conversion. If you want to support Unicode then everything is much more complicated since "converting the first character to uppercase" may be meaningless in other languages. You have to use a Unicode library written by experts for this.
To illustrate how complicated it is, consider the following case in English. Converting the three code-point sequence 'file' (with f-i ligature) shall break the first codepoint into two separate letters resulting in 'File'. Please note that the standard C/C++ interfaces for doing case classification and conversion don't take such cases into account, so it's even impossible to implement them to support Unicode correctly.
#include <iostream>
using namespace std;
void capitalize (string &s)
{
bool cap = true;
for(unsigned int i = 0; i <= s.length(); i++)
{
if (isalpha(s[i]) && cap == true)
{
s[i] = toupper(s[i]);
cap = false;
}
else if (isspace(s[i]))
{
cap = true;
}
}
}
(Only works with 'ASCII' characters.)
std::wstring s = L"apple";
if(islower(s.at(0) <= 'z' ? s.at(0) : 'A'))
s[0] += 'A' - 'a';
Or if you are feeling fancy and feel like torturing any future readers of your code:
std::wstringstream wss;
wss << std::uppercase << s[0]
<< std::nouppercase << s.substr(1);
wss >> s;
Related
I was trying to print the last character of a string, for example str[]="This is an example", I tried to print the 'e' of "example" with some functions, but none of them funct as I expected. I know it's more simple to write in the code the position number of the last character, but as in strrchr function, the code work by itself. Is there a function that works similar?
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int main ()
{
char str[] = "This is an example";
char * pch;
pch=strrchr(str,'s');
cout<<str<<endl;
cout<<"Last time 's' was found was in position: "<<pch-str+1<<endl;
cout<<"Last character in this example is "<<str[X];
return 0;
}
From the documentation for strrchr:
The terminating null-character is considered part of the C string. Therefore, it can also be located to retrieve a pointer to the end of a string.
Thus, strrchr(str, '\0')[-1] will have the last character. Note that this is only safe if you're sure str isn't empty.
Simple: use the standard strlen function, as follows:
int main ()
{
char str[] = "This is an example";
char * pch;
pch=strrchr(str,'s');
cout<<str<<endl;
cout<<"Last time 's' was found was in position: "<<pch-str+1<<endl;
size_t X = strlen(str) - 1; // X will be the index of the last character!
cout<<"Last character in this example is "<<str[X];
return 0;
}
Or, just for fun, if you want to handle the case where the string could be empty:
size_t X = strlen(str); X -= !!X; // Non-zero: decrement, Zero: Leave as is
cout<<"Last character in this example is "<<str[X];
Then, for an empty string, cout << str[X] will show whatever the implementation does for a NULL character.
If you don't mind to use std::string this snippet would do the job.
#include <string>
#include <iostream>
int main() {
std::string str = "This is some text";
std::cout << str.back() << std::endl;
}
I assume you choose char[] to avoid allocation or something similar so am not going to discuss std::string as an option.
Three solutions, one in modern C++ using string_view, one using templates ;
and one using std::size and the index operator.
Solution 1.1:
I recommend you use this, its nearly optimal and is much more readable than the alternative. It also doesn't require as much boiler plate to handle empty strings, or strings without null termination.
#include <string_view>
#include <iostream>
int main()
{
std::string_view str = "This is an example";
auto X = str.find_last_of('s');
//
// Make sure the character exists in the string
if (X != std::string_view::npos)
{
std::cout<< str << std::endl;
std::cout<< "Last time 's' was found was in position: " << X << std::endl;
}
else
{
std::cout<<"Character did not exist in string.\n";
}
if (!str.empty()) std::cout<< "Last character in this example is " << str.back();
else std::cout << "Cannot get the last character in an empty string!";
return 0;
}
You can run the solution here:
https://onlinegdb.com/SJK2hjPEB
The same code will work with std::string.
Solution 1.2
This is a compile time only solution, it relies on the string being aggregate constructed or constructed as a string.
template <size_t N>
constexpr char LastCharacter(char (&input)[N])
{
static_assert(N >= 1, "A character array representing a string must have atleast 1 character AND a null terminator.");
return (input[N - 1] == '\0') ? input[N - 2] : input[N - 1];
}
Tests and examples shown here:
https://onlinegdb.com/HJ_IXEd4H
Solution 2
This has the required checks to avoid issues with empty strings.
In this version it is a compile time error to have an empty array. str[] = "" is not an empty array it has 1 character, a null. An empty string has no last character, this needs to be handled. It also should be handled for the strrchr.
If you must use strrchr(...) then consider checking whether the result is nullptr. If a nullptr is returned then the character wasn't found in the string:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cassert>
using namespace std;
int main ()
{
char str[] = {'h', 'e','l', 'l', 'o', '\0'};
//
// Prevent use with an empty array (1 character + 1 null character minimum)
if (std::size(str) > 1)
{
//
// Only allow null terminated strings.
assert( str[std::size(str) - 1] == '\0' );
//
// There skip the last null character and get the last character
// No null character, not compensation needed
cout<<"Last character in this example is "<< str[ std::size(str) - 2 ];
}
else
{
cout << "Cannot process empty string\n";
}
return 0;
}
https://onlinegdb.com/SkrP2Q_NB
Please note, defining strings as arrays enables strings to exist without null terminators. In that case the above solution does not function. If you want to handle that case you need to check for the existance of a null terminator and if it is present compensate in code. assert causes an error if there isn't a null terminator.
--
To elaborate on the problem with strrchr. The function requires a null terminated string.
The terminating null-character is considered part of the C string.
Therefore, it can also be located to retrieve a pointer to the end of
a string.
http://www.cplusplus.com/reference/cstring/strrchr/
This was quoted by the previous answer, but for completeness also here.
The datatype you are using allows a character array with no null termination:
char data[] = {'a', 'b', 'c'};
That is what the assert handles in the solution 2.
I'm trying to read numbers from a string e.g.
if
string str = "1Hi15This10";
I want to get (1,15,10)
I tried by index but I read 10 as 1 and 0 not 10.
I could not use getline because the string is not separated by anything.
Any ideas?
without regex you can do this
std::string str = "1Hi15This10";
for (char *c = &str[0]; *c; ++c)
if (!std::isdigit(*c) && *c != '-' && *c != '+') *c = ' ';
the integers are now seperated by a space delimiter which is trivial to parse
IMHO the best way would be to use a regular expression.
#include <iostream>
#include <iterator>
#include <string>
#include <regex>
int main() {
std::string s = "1Hi15This10";
std::regex number("(\\d+)"); // -- match any group of one or more digits
auto begin = std::sregex_iterator(s.begin(), s.end(), number);
// iterate over all valid matches
for (auto i = begin; i != std::sregex_iterator(); ++i) {
std::cout << " " << i->str() << '\n';
// and additional processing, e.g. parse to int using std::stoi() etc.
}
}
Output:
1
15
10
Live example here on ideone.
Yes, you could just write your own loop for this, but:
you will probably make some silly mistake somewhere,
a regular expression can be adapted to serve many different search patterns; e.g. what if tmr you decide you want to support decimal/negative/floating point numbers; these cases and many others will be easily supported with a regex, probably not so much with your custom solution :)
This code here is for reversing words in a string. The problem is that it only reverses the first word in the string. When I ran a trace I found that it is stopping after encountering the statement if(s[indexCount] == '\0') break;
Why the code is getting null character every time the first word is reversed even though some other character is present after the first word.
#include <iostream>
using namespace std;
int main()
{
string s;
char tchar;
int indexCount=0,charCount=0,wordIndex;
cin>>s;
while(1){
if(s[indexCount]==' ' && charCount==0) continue;
if(s[indexCount]==' ' || s[indexCount]=='\0' ){
wordIndex=indexCount-charCount;
charCount=indexCount-1;
while(charCount!=wordIndex && charCount>wordIndex){
tchar=s[wordIndex];
s[wordIndex]=s[charCount];
s[charCount]=tchar;
charCount--;
wordIndex++;
}
if(s[indexCount] == '\0') break;
indexCount++; charCount=0;
}
else{
charCount++;
indexCount++;
}
}
cout<<"\nReveresed words in the string : \n\t"<<s<<endl;
return 0;
}
Also I'm using while(1). Does it make this a bad code?
The problem indeed lies with the method of input. cin >> string_variable will consider whitespace to be a delimiter. That is why only the first word is being entered. Replace cin >> s; with getline(cin, s); and it will work correctly.
First of all I want to point out that
cin >> stringObject;
will never ever read space character! so inserting My name is geeksoul will cause above code to read only My and leave everything else in the buffer!
To read space character you should use getline function like this
std::getline(std::cin, stringObject);
read about getline
Second The standard doesn't say that in case of an std::string '\0' is any special character. Therefore, any compliant implementation of std::string should not treat '\0' as any special character. Unless of course a const char* is passed to a member function of a string, which is assumed to be null-terminated.
If you really want to check your string with null terminating character then you should consider using stringObject.c_str() which converts your C++ style string to old school C style string!
Check this for c_str
Finally this might be helpful for you!
Quick tip.
If you reverse all characters in the whole strings, and then all characters between each pair of consecutive spaces, you will achieve the same result, with way simple code, like this: (Note, this may not compile or be slightly buggy (haven't compiled or anything), but should convey the basic idea)
void reverseWords(std::string& aString) {
std::reverse(aString.begin(), aString.end());
size_t lastSpaceIndex = 0;
for (size_t index = 0; index != aString.size(); ++index) {
if (aString[index] == ' ') {
std::reverse(aString.begin() + lastSpaceIndex + 1, aString.begin() + index);
lastSpaceIndex = index;
}
}
}
I have a std::string and wish for the first letter to be capitalized and the rest lower case.
One way I could do this is:
const std::string example("eXamPLe");
std::string capitalized = boost::to_lower_copy(example);
capitalized[0] = toupper(capitalized[0]);
Which would yield capitalized as:
"Example"
But perhaps there is a more straight forward way to do this?
If the string is indeed just a single word, std::string capitalized = boost::locale::to_title (example) should do it. Otherwise, what you've got is pretty compact.
Edit: just noticed that the boost::python namespace has a str class with a capitalize() method which sounds like it would work for multi word strings (assuming you want what you described and not title case). Using a python string just to gain that functionality is probably a bad idea, however.
A boost-less solution is:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
const std::string example("eXamPLe");
std::string s = example;
s[0] = toupper(s[0]);
std::transform(s.begin()+1, s.end(), s.begin()+1, tolower);
std::cout << s << "\n";
}
I think the string variable name is example and the string stored in it is "example".
So try this:
example[0] = toupper(example[0]);
for(int i=1 ; example[i] != '\0' ; ++i){
example[i] = tolower(example[i]);
}
cout << example << endl;
This might give you the first character CAPITALIZED and the rest of the string becomes lowercase.
It's not quite different from the original solution but just a different approach.
I need a function to convert "explicit" escape sequences into the relative non-printable character.
Es:
char str[] = "\\n";
cout << "Line1" << convert_esc(str) << "Line2" << endl:
would give this output:
Line1
Line2
Is there any function that does this?
I think that you must write such function yourself since escape characters is a compile-time feature, i.e. when you write "\n" the compiler would replace the \n sequence with the eol character. The resulting string is of length 1 (excluding the terminating zero character).
In your case a string "\\n" is of length 2 (again excluding terminating zero) and contains \ and n.
You need to scan your string and when encountering \ check the following char. if it is one of the legal escapes, you should replace both of them with the corresponding character, otherwise skip or leave them both as is.
( http://ideone.com/BvcDE ):
string unescape(const string& s)
{
string res;
string::const_iterator it = s.begin();
while (it != s.end())
{
char c = *it++;
if (c == '\\' && it != s.end())
{
switch (*it++) {
case '\\': c = '\\'; break;
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
// all other escapes
default:
// invalid escape sequence - skip it. alternatively you can copy it as is, throw an exception...
continue;
}
}
res += c;
}
return res;
}
You can do that fairly easy, using the boost string algorithm library. For example:
#include <string>
#include <iostream>
#include <boost/algorithm/string.hpp>
void escape(std::string& str)
{
boost::replace_all(str, "\\\\", "\\");
boost::replace_all(str, "\\t", "\t");
boost::replace_all(str, "\\n", "\n");
// ... add others here ...
}
int main()
{
std::string str = "This\\tis\\n \\\\a test\\n123";
std::cout << str << std::endl << std::endl;
escape(str);
std::cout << str << std::endl;
return 0;
}
This is surely not the most efficient way to do this (because it iterates the string multiple times), but it is compact and easy to understand.
Update:
As ybungalobill has pointed out, this implementation will be wrong, whenever a replacement string produces a character sequence, that a later replacement is searching for or when a replacement removes/modifies a character sequence, that should have been replaced.
An example for the first case is "\\\\n" -> "\\n" -> "\n". When you put the "\\\\" -> "\\" replacement last (which seems to be the solution at a first glance), you get an example for the latter case "\\\\n" -> "\\\n". Obviously there is no simple solution to this problem, which makes this technique only feasible for very simple escape sequences.
If you need a generic (and more efficient) solution, you should implement a state machine that iterates the string, as proposed by davka.
I'm sure that there is, written by someone, but it's so trivial that I doubt it's been specifically published anywhere.
Just recreate it yourself from the various "find"/"replace"-esque algorithms in the standard library.
Have you considered using printf? (or one of its relatives)
Here's a cute way to do it on Unixy platforms.
It calls the operating system's echo command to make the conversion.
string convert_escapes( string input )
{
string buffer(input.size()+1,0);
string cmd = "/usr/bin/env echo -ne \""+input+"\"";
FILE * f = popen(cmd.c_str(),"r"); assert(f);
buffer.resize(fread(&buffer[0],1,buffer.size()-1,f));
fclose(f);
return buffer;
}