#include <bits/stdc++.h>
using namespace std;
int main()
{
string s1 = "Alice";
s1 +='\0';
s1 +='\0';
cout << s1.size() << endl; // output: 7
string s2 = "Alice";
s2 += "\0";
s2 += "\0";
cout << s2.size() << endl; // output: 5
}
What is wrong here?
Please explain the difference between role of single quotes and double quotes in concatenation.
s1 +='\0';
adds the character to s1 regardless of what the character is.
s2 += "\0";
adds a null terminated string to s2. Because of that, the embedded null character of the RHS is seen as a string terminator for the purposes of that function. In essence, that is equivalent to
s2 += "";
That explains the difference in output that you observed.
You can use std::string::append to append embedded null characters of a char const* object.
s2.append("\0", 1);
Related
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str = "Hello";
string s = str[0] + str[1];
cout << s;
return 0;
}
Why does this code gives an error, even if we can concatenate strings?
the reason this fails
std::string s = str[0] + str[1];
is because str[0] and str[1] return a char (H and e):
std::string s = 'H' + 'e';
and adding two chars will not concatenate them, instead their values will be added together. Every character has an assigned number (look up ASCII table)
std::string s = 72 + 101;
and this will fail, as assigning the number 173 to a string doesn't really make sense to the compiler.
there are multiple ways to concatenate variables together, in this case the most simple solution would be
std::string s { str[0], str[1] };
This will be limited to chars though, so you couldn't say { str[0], str[1], 500 }. Therefore the general way to concatenate any number of data, is to use std::ostringstream, found in the header <sstream>. This how it is used:
std::ostringstream stream;
stream << str[0] << str[1] << 500;
std::string s = stream.str();
Read here why using namespace std; is considered bad practice and here why <bits/stdc++.h> is to be avoided.
str[0] and str[1] are giving you characters, not strings. Adding them gives you another character, which cannot be casted to a string.
You can construct a new string with a substring of the first part of the string you want to concatenate, and then insert the substring of the second part of the string you want to concatenate, like so:
// Construct new string that contains the first character of str
string s(str.begin(), str.begin() + 1);
// Add the second character of str onto the end of s
s.insert(s.end(), str.begin() + 1, str.begin() + 2);
I declare 2 string type strings, qhich is s, s1. I use s string with 'cin'
and I paste 3 values in s1. Then I print with 'cout' but it can't print string.
Here is my code
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
string s,s1;
cin>>s;
s1[0]=s[1];
s1[1]=s[2];
s1[2]=s[3];
s1[3]='\0';
cout<<s1<<endl;
return 0;
}
s1 was not empty.... cout<<s1[0]<<s1[1]<<s1[2] and see.
Why s1 can't print?
Probably, the easiest way to accomplish OP's task is to use a library function like substr() which takes care of all the details the posted code is missing (and already pointed out):
memory management. The second string s1 is empty, so trying to write its first four (unallocated) elements is undefined behavior. In general, s1 should be resized to the needed length.
null terminator. A std::string can manage it's internal representation and always returns a null-terminated string via its member functions c_str and data (since C++11).
That's how it could be done:
#include <iostream>
#include <string>
int main()
{
std::string s;
std::cin >> s;
std::string s1;
std::string::size_type start_pos = 1,
count = 3;
if ( s.size() > start_pos )
s1 = s.substr(start_pos, count);
std::cout << s1 << '\n';
}
s1 doesn't have any characters. You're trying to change the value of characters that do not exist.
Your program has undefined behaviour, and might just as easily open a llama zoo, reverse the polarity of the Earth's magnetic field, or solve cold fusion in the bath.
Make s1 the correct size before writing things to it;
Don't write a '\0' to the end; this is not a C string; that is unnecessary. C++ strings look after themselves.
Here's an example:
#include <iostream>
#include <cassert>
int main()
{
std::string s, s1;
std::cin >> s;
assert(s.size() >= 4);
s1.resize(3);
s1[0] = s[1];
s1[1] = s[2];
s1[2] = s[3];
std::cout << s1 << std::endl;
}
live demo
You can not assign as s1[0] = s[1]
Correct way is using assign function as:
string s,s1;
cin>>s;
s1.assign(s.begin()+1,s.begin()+4);
cout<<s1<<endl;
String assignment cannot be done by assigning indexes without fixing or defining the size of the string. It may cause a string subscript error. If you want to do this, I think string concatenation is the best method; that is, by adding substrings or string indexes into string. I've given some code below that uses the string concatenation method.
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int main()
{
string s,s1="";
cin>>s;
s1= s1 + s[1];
s1= s1 + s[2];
s1= s1 + s[3];
cout<<s1<<endl;
return 0;
}
We know in string literal, "\u94b1" will be converted to a character, in this case a Chinese word '钱'. But if it is literally 6 character in a string, saying '\', 'u', '9', '4', 'b', '1', how can I convert it to a character manually?
For example:
string s1;
string s2 = "\u94b1";
cin >> s1; //here I input \u94b1
cout << s1 << endl; //here output \u94b1
cout << s2 << endl; //and here output 钱
I want to convert s1 so that cout << s1 << endl; will also output 钱.
Any suggestion please?
In fact the conversion is a little more complicated.
string s2 = "\u94b1";
is in fact the equivalent of:
char cs2 = { 0xe9, 0x92, 0xb1, 0}; string s2 = cs2;
That means that you are initializing it the the 3 characters that compose the UTF8 representation of 钱 - you char just examine s2.c_str() to make sure of that.
So to process the 6 raw characters '\', 'u', '9', '4', 'b', '1', you must first extract the wchar_t from string s1 = "\\u94b1"; (what you get when you read it). It is easy, just skip the two first characters and read it as hexadecimal:
unsigned int ui;
std::istringstream is(s1.c_str() + 2);
is >> hex >> ui;
ui is now 0x94b1.
Now provided you have a C++11 compliant system, you can convert it with std::convert_utf8:
wchar_t wc = ui;
std::codecvt_utf8<wchar_t> conv;
const wchar_t *wnext;
char *next;
char cbuf[4] = {0}; // initialize the buffer to 0 to have a terminating null
std::mbstate_t state;
conv.out(state, &wc, &wc + 1, wnext, cbuf, cbuf+4, next);
cbuf contains now the 3 characters representing 钱 in utf8 and a terminating null, and you finaly can do:
string s3 = cbuf;
cout << s3 << endl;
You do this by writing code that checks whether the string contains a backslash, a letter u, and four hexadecimal digits, and converts this to a Unicode code point. Then your std::string implementation probably assumes UTF-8, so you translate that code point into 1, 2, or 3 UTF-8 bytes.
For extra points, figure out how to enter code points outside the basic plane.
With utfcpp (header only) you may do:
#include </usr/include/utf8.h>
#include <cstdint>
#include <iostream>
std::string replace_utf8_escape_sequences(const std::string& str) {
std::string result;
std::string::size_type first = 0;
std::string::size_type last = 0;
while(true) {
// Find an escape position
last = str.find("\\u", last);
if(last == std::string::npos) {
result.append(str.begin() + first, str.end());
break;
}
// Extract a 4 digit hexadecimal
const char* hex = str.data() + last + 2;
char* hex_end;
std::uint_fast32_t code = std::strtoul(hex, &hex_end, 16);
std::string::size_type hex_size = hex_end - hex;
// Append the leading and converted string
if(hex_size != 4) last = last + 2 + hex_size;
else {
result.append(str.begin() + first, str.begin() + last);
try {
utf8::utf16to8(&code, &code + 1, std::back_inserter(result));
}
catch(const utf8::exception&) {
// Error Handling
result.clear();
break;
}
first = last = last + 2 + 4;
}
}
return result;
}
int main()
{
std::string source = "What is the meaning of '\\u94b1' '\\u94b1' '\\u94b1' '\\u94b1' ?";
std::string target = replace_utf8_escape_sequences(source);
std::cout << "Conversion from \"" << source << "\" to \"" << target << "\"\n";
}
what is the difference between initializing the string in the following ways?
string s = "Hello World";
and
string s[] = {"Hello World"};
From what i understand the former is a class? And the latter an array? Moreover, are there any other ways apart from these two?
In the first example, you define one object of class string.
In the second, you declare an array of strings of undefined length (computed by compiler, based on how many objects you define in the initializer list) and you initialize one string object with "Hello World." So You create an array of size 1.
string s = "Hello World";
string s2[] = {"Hello World"};
After this, s and s2[0] contains strings with identical characters in them.
Statement
string s = "Hello World";
creates an object of class std::string from a string literal, while
string s[] = {"Hello World"};
creates an array (of length 1) of std::string objects.
Other ways to construct a string from a string literal are the following:
string s("Hello World"); // using old style constructor call
string s {"Hello World"}; // using new brace initializer (preffered way)
#include <string>
#include <iostream>
using namespace std;
int main(void) {
// C-style string; considered "deprecated", better use string class
char *s1 = "Hello World";
cout << s1 << endl;
// Copy constructors
string s2 = "Hellow World";
cout << s2 << endl;
string s3("Hello World");
cout << s3 << endl;
string s4{"Hello World"}; // C++11, recommended
cout << s4 << endl;
// Move constructor; C++11
string s5 = move("Hello World");
cout << s5 << endl;
return 0;
}
This defines an array of type string and contains exactly one string element representing the Hello World character sequence.
string s[] = {"Hello World"}; // array of string; not a string by itself
This question already has answers here:
Easiest way to convert int to string in C++
(30 answers)
Closed 8 years ago.
Here str2 is a string I need to append and str1 is the string I append onto str2. After I append last to str2 I need to append a number (int cnt) to str2. So I am using the below code, which came to my mind and it is working. Is it wrong to code like this, since I saw the usage of string s = lexical_cast<string>(a); and itoa (i,buffer,10); implementations where compiler complaints about the library.
string str2;
string str1;
int cnt;
str2 += str1 ;
str2 += char(cnt+48);//cnt converted to ASCII char and appended;
This statement
str2 += char(cnt+48);
is bad. Firstly it uses magic number 48. It would be better to write at least as
str2 += char( cnt + '0' );
Secondly the code will work only if cnt contains a number with one digit.
It would be better to use standard function std::to_string For example
str2 += std::to_string( cnt );
If you don't want to use c++11 and its std::to_string(...) you can use ostringstream class.
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
ostringstream ss;
ss << 1;
string str = ss.str();
cout << str << endl;
return 0;
}
Output:
1