Getting error while initializing string with string character array? [duplicate] - c++

This question already has answers here:
no viable conversion from 'value_type' (aka 'char') to 'string' (aka 'basic_string<char, char_traits<char>, allocator<char> >')
(1 answer)
Initializing a string with a single character
(1 answer)
Closed 1 year ago.
I'm trying to initialize this string s1 but Idk why I'm getting this error, This may be due to s[0] is character but why everything turns fine when I initialize and declare same string s1 but in diffrent lines, one after another.
#include <bits/stdc++.h>
int main()
{
std::string s = "text";
std::string s1 = s[0];
std::cout << s1;
}
Error:
error: conversion from '__gnu_cxx::__alloc_traits<std::allocator<char>, char>::value_type'
{aka 'char'} to non-scalar type 'std::__cxx11::string' {aka
'std::__cxx11::basic_string<char>'} requested
std::string s1 = s[0];
^
This is working fine:
#include <bits/stdc++.h>
int main()
{
std::string s = "text";
std::string s1;
s1 = s[0];
std::cout << s1;
}

There's no constructor for char. There's a copy assignignment, which works for the second snippet.
However, you can write either like
std::string s1 ( 1, s[0] );

std::string s1 = s[0]; is initialization, it doesn't work because std::string doesn't have any constructor taking a single char.
s1 = s[0]; is assignment, it works because std::string has a operator= taking a single char.

If we take a look at the documentation, we can see that
std::string has no constructor that takes a char type - cppreference.com
It does have an overload for the operator= that can take a
char - cppreference.com
[The copy assignment that takes a char] replaces the contents with
character ch as if by assign(std::addressof(ch), 1)
As to why, consider the fact that the std::string already has so called fill-constructor, string s(n, val), that takes an initial value val and fills the string with n copies of it. So there's no need to have special case for n == 1:
std::string s1 = "text";
std::string s2(1, s[0]); // One char of value s[0]

#include <bits/stdc++.h>
using namespace std;
int main()
{
string s = "text";
string s1;
s1 = s;
cout << s1;
}
the code should work now.

Related

Initializing a string with a single character

I want to initialize a std::string with a single character. The following code doesn't work:
int main()
{
string s = 'c';
cout<<s;
return 0;
}
Error:
error: conversion from ‘char’ to non-scalar type ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ requested
string s = 'c';
But the following does work. Why is it so?
int main()
{
string s;
s = 'c';
cout<<s;
return 0;
}
Output:
c[Finished in 0.8s]
When you do
string s = 'c';
you are basically invoking constructor initialisation rather than an assignment operation. But there isn’t any constructor for std::string that takes only a single char as input. There is however one std::string(n, c), where n is the number of characters c in the string.
When you do
s = 'c'
you do an assignment operation, invoking the overloaded string::operator= (string& operator= (char c);) for std::string. Now this method is overloaded to accept a single char as input as well, as you can see from the code snippet at this reference as well as at this one.
std::string str1;
// ...
// (4) operator=( CharT );
str1 = '!';
Additionally, std::string::assign doesn’t accept a single char, similar to the constructor.

Why I can't assign string::back to string?

I write a simple program:
Get last character of string1 and assign it to string2.
It's like:
#include<iostream>
#include<string>
int main(int argc, char const *argv[])
{
std::string s1 = "abc!";
std::string s2 = s1.back();
std::cout << s1;
return 0;
}
However, I get a compile error:
conversion from ‘__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type {aka char}’ to non-scalar type ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ requested
I don't know this error exactly means.
It's seems like some type conversion error occur.
But the return value of string::back should be char, right?
Why I can't assign it to another string?
And how I can give last character of s1 to s2?
It's because std::string does not have an implicit constructor which takes just a single character parameter, that's why conversion from char to std::string fails. Instead you can use:
// 1. Constructor with length + char
std::string s2(1, s1.back());
// 2. Constructor which takes an std::initializer_list<char>
std::string s2{s1.back()};
A string is a collection of characters, the back of a string is a character (i.e., just an element of the collection), not a string.
You can achieve what you want by using the following constructor overload of std::string:
std::string s2(1, s1.back());
That is, construct s2 as a one-character-length string with the value s1.back().
Hope you are trying to create a new string s2 out of the last character of string s1.
You can achieve that using the solution below:
#include<iostream>
#include<string>
int main()
{
std::string s1 = "abc!";
std::string s2;
s2 = s1.back();
std::cout << s1;
std::cout << s2;
return 0;
}

Why std::string concatenation in one expression gives different result than char by char?

I'm concatenating 3 chars from the middle of a std::string. If I do it char by char, I get the expected result, but if I do it in only one expression, I get a weird result. Why?
#include <string>
#include <iostream>
using namespace std;
int main()
{
string s1 = "abcdefghijklmnopq";
string s2 = "";
string s3 = "";
s3+=s1[4];
s3+=s1[5];
s3+=s1[6];
cout << s3 << endl; // Expected behaviour
s2=s1[4]+s1[5]+s1[6];
cout << s2 << endl; // ?????
}
s1[4]+s1[5]+s1[6] uses the built-in + on a char type: every argument is promoted to an int and the expression is an int type. When this is assigned to s2, the overloaded = operator to char is called, and the expression is truncated to a char prior to the assignment. If char is signed on your platform, then this is implementation defined. See http://en.cppreference.com/w/cpp/language/implicit_conversion.
s3+=s1[4]; and company uses the overloaded += operator on the std::string for a char argument. That is defined to concatenate the char to the string.
Finally from C++14 onwards, you could use the beautiful
s2 = ""s + s1[4] + s1[5] + s1[6];
if substr cannot come to your rescue (s2 = s1.substr(4, 3); would do the job in this particular case). Note the user defined literal ""s defined in the C++14 Standard Library.

default argument declaration :why a default string parameter must be const [duplicate]

This question already has answers here:
How come a non-const reference cannot bind to a temporary object?
(11 answers)
Closed 7 years ago.
what is the reason of having to put that const on the last parameter of my function(it has default argument declaration) if it was not default, it would not need that const
string make_plural(string &word, size_t c, const string &ending = "s")
{
return c > 1 ? word + ending : word;
}
the error is : 'default argument' : cannot convert from 'const char [2]' to 'std::string &'
but i cannot understand why. can any body explain please.
I have found out the answer myself.
we have to put that const because string literals are const and in the code we were initializing a const string to a plain reference which is in error.
to make it clear look below:
string &r="some string";
is in error but
const string &r="some string";
is valid
and if :
string make_plural(string &word, size_t c,const string &ending = "s")
{
return c > 1 ? word + ending : word;
}
if the first parameter was a plain reference then the call could be:
string str = "thing";
cout << make_plural(str,2) << endl;
but if you want the call to be:
cout << make_plural("thing",2) << endl;
you have to add const for the first parameter as follows
string make_plural(const string &word, size_t cnt,const string &ending = "s")
{
return cnt > 1 ? word + ending : word;
}
reasons and rules to initializing parameter are the same as variables so:
plain references cannot be initialized by const values such as a string literals that are consts.

C++: Why is 'operator+=' defined but not 'operator+' for strings? [duplicate]

This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 8 years ago.
How come operator+= is defined for std::string but operator+ is not defined? See my MWE below (http://ideone.com/OWQsJk).
#include <iostream>
#include <string>
using namespace std;
int main() {
string first;
first = "Day";
first += "number";
cout << "\nfirst = " << first << endl;
string second;
//second = "abc" + "def"; // This won't compile
cout << "\nsecond = " << second << endl;
return 0;
}
You need to convert one of the raw string literals to std::string explicitly. You can do it like others already mentioned:
second = std::string("abc") + "def";
or with C++14, you will be able to use
using namespace std::literals;
second = "abc"s + "def";
// note ^
Those aren't std::strings, they are const char *. Try this:
second = std::string("abc") + "def";
C++: Why is 'operator+=' defined but not 'operator+' for strings?
It is. It requires at least one of the operands to be an std::string:
int main()
{
std::string foo("foo");
std::string bar("bar");
std::string foobar = foo + bar;
std::cout << foobar << std::endl;
}
The problem in your case is that you are trying to add string literals "abc" and "def". These have type const char[4]. There is no operator+ for these types.
+ will work to concatenate two strings only when at least one operand is of type std::string.
In "abc" + "def", None of the operand is of type std::string.