invalid initializer - c++

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

Related

Ways of initialising a string in 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

How to manipulate character string being pointed to

I'm sure this is an easy question for most but I'm having trouble trying to figure out why I can't manipulate this sting and better yet how I should go about doing it. So for example we have:
char *str1="Hello World";
All I want to do is manipulate the string that is being pointed to by 'str1'. For example, as shown below, I could output the string and see the original. Then I could add a null character in there and shorten it.
cout << str1 << '\n';
str1[5] = '\0';
cout << str1;
I've also tried:
cout << str1 << '\n';
*(str1+4) = '\0';
cout << str1;
Either way I'm hoping to see something like this:
Hello World
Hello
The error I'm getting in both cases is when I try to alter the string. I know it would be easier to just declare str1 as an array (char str1[] = ....) but I'm given the constraint of having to use the dreaded char *
String literals are stored in read-only memory. You cannot modify them. In fact, in modern C++, attempting to initialise str1 the way you did will give an error. It should be a const char*:
const char* str1 = "Hello World";
This makes it clear that you shouldn't be modifying the chars.
If you want a copy of the string that you can manipulate, you should make str1 an array:
char str1[] = "Hello World";
When you initialise an array with a string literal, the characters are copied into the array.
So after all of the help I've received from you all I went with first determining the length of the strings, initializing an array of the same size+1, and then iterating through the original to save it into an array. Then I was able to manipulate it as i pleased.
int someFunc(char *inpStr){
int counter = 0;
//Find the length of the input string
while(inpStr[counter]!='\0'){counter++;}
//Input initialize an array of same size
char strArray[counter+1];
//Copy whats in the char * to the array and make sure it ends with null
for(int i=0;i<=counter;i++){strArray[i]=*(inpStr+i);}
strArray[counter]='\0';
.....
return 0;
}
Thanks for all the help!
Why you cannot change the str1 has been explained aptly by Joseph. But still if you want to modify it you can use something like this:
char *str = "hello";
char *ptr = new char[strlen(str)+1];
strcpy(ptr,str);
ptr[2] = 'd';
str = ptr;
I hope this solves your problem.

output char* to std::string C++

So given:
struct MemoryStruct {
char *memory;
size_t size;
};
char* memory holds a curl return, XML doc.
I am doing:
if(chunk.memory) {
std::cout << "char size is " << sizeof(chunk.memory) << std::endl;
std::string s = "";
for (int c = 0; c<sizeof(chunk.memory); c++) {
s.push_back(chunk.memory[c]);
}
std::cout << "s: " << s.c_str() << std::endl;
}
I am only getting back <?xm
So sizeof() I think is return the total bytes in the char*
How do I get what the actual value is a char*. So basically the whole curl return. Which is 5 lines of XML?
sizeof(chunk.memory) will give always you size of a pointer which in your case seems to be 4. That's why you see only 4 characters in your std::string.
If your curl return or whatever else is terminated by \0, then you can directly do the following
std::string s(chunk.memory);
If your char * is not terminated by \0, then you need to know the length of the string - you cannot use sizeof(chunk.memory) for this. If your chunk.size contains the correct size, then you can use
std::string s(chunk.memory, chunk.size);
std::string constructor can accept char* and data length (see the docs); Example:
std::string s(chunk.memory, chunk.size);
So container will pre-allocate need space for your string and initialize with it.
In MemoryStruct memory is the pointer to the first returned character and size is the number of characters returned. You want to initialize a string with this data so you will need to do:
s.assign(chunk.memory, chunk.size);

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';

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.