Ways of initialising a string in c++ - c++

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

Related

string concatenation of character and string

#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);

Cutting off the end of a char *

So i have a char *. And i want to cut off some bit at the end. So
char *sentence = "My name is Ted";
How do I cut off the Ted. I could make it a string and then use substring (coming from Java thats my go to method) but id rather not do that way. But im not sure how to do it with a char *.
EDIT: Further on the problem. The issue is in a function that takes a process and is meant to return the location when that process is started from. Thats fine i can get that. But the parameter char *procLocation is passed by reference so the location will be sent back there.
I can only get the location that includes the name of the process. I want to cut off the name of the process and just return the location. Ive tried making the location a string and doing a substring (string - length of the processName). Thats fine. But
procLocation = location.c_str(); // where location.substr is the location - the process name
gives back an error: error C2440: '=' : cannot convert from 'const char *' to 'char *'
Since that is a string literal, you can't modify it.
If you did:
char sentence[] = "My name is Ted";
You could simply set the character before Ted to \0.
You might be better off using std::string though.
Instead of cutting off your literal, you could use std::string constructor that copies fewer characters than is available in your char*:
const char *data = "Hello, Ted!";
string s(data, data+8);
cout << s << endl;
This prints Hello, T
This approach is less wasteful than making a std::string and taking a substring.
To your original problem, as you're coming from Java, you should (should, in the sense of RFC2119) definitely use std::string:
#include <string>
#include <iostream>
using namespace std;
int main(int argc, const char** argv) {
// copy c-string to std::string
string arg0 = argv[0];
cout << arg0 << endl;
// find last occurrence of path separator
size_t found = arg0.find_last_of("/\\");
// split off filename part of string
cout << arg0.substr(0,found) << endl;
return 0;
}
Further, you should not (should not, in the sense of RFC2119) declare the char array as a char pointer, but as a char array:
char[] s0 = "Hello World!"; // <-- is better
char * s1 = "Hello World!"; // <-- avoid this
See this post for actual reasons why this is better. It also gives the reasons for why not to modify such rvalue strings.
You've tagged the question 'c++' and 'string' but you say you don't want to do this with string and substr ? Not sure why that is. You should prefer these over char* and C style string manipulation functions wherever possible.
To do it the C++ way:
string sentence = "My name is Ted";
cout << "\"" << sentence.substr(0, sentence.rfind(' ') ) << "\"" << endl;
Although you could (modifying your code slightly so that you have a mutable string) do this in C:
char sentence[] = "My name is Ted";
*strrchr(sentence, ' ') = '\0';
printf("\"%s\"\n", sentence);

How concatenate a string and a const char?

I need to put "hello world" in c.
How can I do this ?
string a = "hello ";
const char *b = "world";
const char *C;
string a = "hello ";
const char *b = "world";
a += b;
const char *C = a.c_str();
or without modifying a:
string a = "hello ";
const char *b = "world";
string c = a + b;
const char *C = c.c_str();
Little edit, to match amount of information given by 111111.
When you already have strings (or const char *s, but I recommend casting the latter to the former), you can just "sum" them up to form longer string. But, if you want to append something more than just string you already have, you can use stringstream and it's operator<<, which works exactly as cout's one, but doesn't print the text to standard output (i.e. console), but to it's internal buffer and you can use it's .str() method to get std::string from it.
std::string::c_str() function returns pointer to const char buffer (i.e. const char *) of string contained within it, that is null-terminated. You can then use it as any other const char * variable.
if you just need to concatenate then use the operator + and operator += functions
#include <string>
///...
std::string str="foo";
std::string str2=str+" bar";
str+="bar";
However if you have a lot of conacatenation to do then you can use a string stream
#include <sstream>
//...
std::string str1="hello";
std::stringstream ss;
ss << str1 << "foo" << ' ' << "bar" << 1234;
std::string str=ss.str();
EDIT: you can then pass the string to a C function taking a const char * with c_str().
my_c_func(str1.c_str());
and If the C func takes a non const char * or require ownership you can do the following
char *cp=std::malloc(str1.size()+1);
std::copy(str1.begin(), str2.end(), cp);
cp[str1.size()]='\0';

invalid initializer

This code keep saying : error: invalid initializer
char * ss = "hello world";
char s[10] = ss;
std::transform(s, s + std::strlen(s), s, static_cast<int(*)(int)>(std::toupper));
How can it be fixed?
Your initializer of the array with a C string is invalid. The good news is that you do not need it at all:
char * ss = "hello world";
char s[12];
std::transform(ss, ss + std::strlen(ss)+1, s, static_cast<int(*)(int)>(std::toupper));
cerr << s << endl;
Note that I padded your s array with an extra element for the terminating zero.
char s[10] = ss;
This tries to set an array's value equal to a pointer, which doesn't make any sense. Also, ten bytes isn't enough (there's a terminating zero byte on the end of a C-style string). Try:
char s[20];
strcpy(s, ss);
Your array assignment is illegal and, in the case of your code, isn't needed in the first place.
const char * ss = "hello world";
char s[12];
std::transform(ss, ss + std::strlen(ss)+1, s, static_cast<int(*)(int)>(std::toupper));
You can't assign a pointer to an array because you can't assign anything to arrays but initialiser lists. You need to copy the characters from ss to s. Also, an array of size 10 is too small to hold "hello world". Example:
char * ss = "hello world";
char s[12] = {}; // fill s with 0s
strncpy(s, ss, 11); // copy characters from ss to s
Alternatively, you could do
char s[] = "hello world"; // create an array on the stack, and fill it with
// "hello world". Note that we left out the size because
// the compiler can tell how big to make it
// this also lets us operate on the array instead of
// having to make a copy
std::transform(s, s + sizeof(s) - 1, s, static_cast<int(*)(int)>(std::toupper));

Declaring array using a variable in C++

I am writing a program that needs to take text input, and modify individual characters. I am doing this by using an array of characters, like so:
char s[] = "test";
s[0] = '1';
cout << s;
(Returns: "1est")
But if I try and use a variable, like so:
string msg1 = "test";
char s2[] = msg1;
s2[0] = '1';
cout << s1[0]
I get an error: error: initializer fails to determine size of 's2'
Why does this happen?
C-style arrays require literal values for initialization. Why use C-style arrays at all? Why not just use std::string...
string msg1 = "test";
string s2 = msg1;
s2[0] = '1';
cout << s2[0];
The space for all the variables is allocated at compile time. You're asking the compiler to allocate space for an array of chars called s2, but not telling it how long to make it.
The way to do it is to declare a pointer to char and dynamically allocate it:
char *s2;
s2 = malloc(1+msg1.length()); // don't forget to free!!!!
s2 = msg1; // I forget if the string class can implicitly be converted to char*
s2[0] = '1'
...
free(s2);
I think char a[] can't be initialized by a string.
Edit: "a string" is actually a c-type string (char array with '\0' at the end).
$8.5.1 and $8.5.2 talk about rules related to initialization of aggregates.