why char * works with const only [duplicate] - c++

This question already has answers here:
What is the type of string literals in C and C++?
(4 answers)
Closed 6 months ago.
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
#define nline "\n"
int main(){
//const char *p="hello world";
// court<<p;
char *p="hello world";
cout<<p;
}
C:\Users\Dell\AppData\Roaming\Sublime Text\Packages\User\cses2.cpp: In function 'int main()':
C:\Users\Dell\AppData\Roaming\Sublime Text\Packages\User\cses2.cpp:7:10: warning: ISO C++ forbids converting a string constant to 'char' [-Wwrite-strings]*
char *p="hello world";
^~~~~~~~~~~~~

"hello world" is a const char[12]. A c-array of 12 constant (!) characters (note that one is for the null terminator).
In early C++ standards it was allowed to get a char * to a string literal due to compatibility with C. Though, it was nevertheless forbidden to actually modify the characters of the string literal via the char *.
This changed in C++11 and since then string literals have proper const correctness.
If you do want a string that can be modified, then use a std::string. Note that the pointer you obtain from the literal is not a string, its just a pointer to a (non-modifiable) c-string. If you want a string rather than a pointer to one, you need to use a string.

Related

understand how char works in c++ [duplicate]

This question already has answers here:
What happened when we do not include '\0' at the end of string in C?
(5 answers)
What is the difference between char s[] and char *s?
(14 answers)
Why do string literals (char*) in C++ have to be constants?
(2 answers)
Closed last year.
I am a C++ newbie. Although many similar questions have been asked and answered, I still find these concepts confusing.
I know
char c='a' // declare a single char c and assign value 'a' to it
char * str = "Test"; // declare a char pointer and pointing content str,
// thus the content can't be modified via point str
char str1[] = "Test"; // declare a char array str1 and assign "Test" to it
// thus str1 owns the data and can modify it
my first question is char * str creates a pointer, how does char * str = "Test"; work? assign a string literal to a pointer? It doesn't make sense to me although it is perfectly legal, I think we can only assign an address to a pointer, however "Test" is a string literal not an address.
Second question is how come the following code prints out "Test" twice in a row?
char str2[] = {'T','e','s','t'}; // is this line legal?
// intializing a char array with initilizer list, seems to be okay to me
cout<<str2<<endl; // prints out "TestTest"
why cout<<str2<<endl; prints out "TestTest"?
char * str = "Test"; is not allowed in C++. A string literal can only be pointed to by a pointer to const. You would need const char * str = "Test";.
If your compiler accepts char * str = "Test"; it is likely outdated. This conversion has not been allowed since C++11 (which came out over 10 years ago).
how does char * str = "Test"; work?
String literals are implicitly convertible to a pointer to the start of the literal. In C++ arrays are implicitly convertible to pointer to their first element. For example int x[10] is implicitly convertible to int*, the conversion results in &(x[0]). This applies to string literals, their type is a const array of characters (const char[]).
how come the following code prints out "Test" twice in a row?
In C++ most features related to character strings assume the string is null terminated, which is implied in string literals. You would need {'T','e','s','t','\0'} to be equivalent to "Test".

In code blocks, Strcpy does not work when I declare a string using char * string but works when I declare it as char string[ ] [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 2 years ago.
#include <stdio.h>
#include <string.h>
int main()
{
char t1string[] = "test";
printf("First String value is %s\n", t1string);
strcpy(t1string, "lgs");
printf("Modified First String value is %s\n", t1string);
char * t2string = "test";
printf("Second String value is %s\n", t2string);
strcpy(t2string, "lgs");
printf("Modified Second String value is %s\n", t2string);
return 0;
}
Looking at the above pair of strcpy usage, I am trying to understand why the strcpy used in the second instance does not work, or is it something specifically wrong (with either my beginner level understanding or code blocks)? Or is it just telling me I am stupid for not simply doing t2string = "lgs";?
Whenever you see a string literal such as "test" in C, that is a const char[5] array which decays for most all purposes into const char *, aka a pointer to a constant character array. The letters 't', 'e', 's', 't' cannot be changed. They are stored in the same area of the program as the program instructions. Those cannot be changed either.
When you declare an array like char s[] = "test"; the constant characters "test" are copied into the array s, exactly as if you had called memcpy(s, "test", 5); From their new location in s they can be modified.
As a backward compatibility support C allows creating char * pointers to const char * arrays. But your program will still crash if you attempt to write into that constant array.

Why string literals are allowed to be assigned to pointer of type char * in C++ [duplicate]

This question already has answers here:
how is char * to string literal valid?
(5 answers)
Closed 5 years ago.
Using visual studio, I declared a pointer of type char * and assigned to it a string literal. I then hovered the mouse over the string literal and it displayed its type: (const char [4])"abc".
How is this allowed? it compiles without warnings or errors, whilst assigning to the pointer an array of type const char [] fails, for obvious reasons, with an error message:
a value of type "const char *" cannot be assigned to an entity of type "char *"
So, why is it allowed for string literals?
int main(void)
{
char *p = "abc"; // no error here
const char str[] = "abc";
//p = str; This line generates an error
return 0;
}
EDIT: answer updated to incorporate info from Story Teller's comment.
In the olden days, const didn't exist, and people wrote things like char* p = "abc" all the time. As long as the didn't then do something like p[0] = 'z', their program worked. To remain compatible with such code, some compilers allow string literals to be assigned to non-const pointers if you don't ask the compiler to be super-strict. If you take advantage of this feature, you still should not ACTUALLY modify the string.

Why is string not getting printed when being initialized by adding string literal and a char [duplicate]

This question already has answers here:
C++ Adding String Literal to Char Literal
(8 answers)
Closed 5 years ago.
In case 1 the output is blank when I initialize a string like this:
#include <iostream>
#include<string>
using namespace std;
//CODE 1
int main()
{
string s="hello" + 'c';
cout<<s<<endl;
return 0;
}
but when I write it this way it works fine:
#include <iostream>
#include<string>
using namespace std;
//CODE 2
int main()
{
string s="hello";
char k='c';
s+=k;
cout<<s<<endl;
return 0;
}
Now I am confused as in another question asked on stack overflow it says that there is no difference between string and std::string when namespace std is used, those answers go by saying that -> There is no functionality difference between string and std::string because they're the same type
std::string vs string in c++
whereas the answers provided for this question are pointing differences:
compiler is g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
When you have
string s="hello" + 'c';
It's equal to
string s=("hello" + 'c');
With ASCII encoding it's the same as
string s=("hello" + 99);
which is the same as
string s=(&"hello"[99]);
That is, you get a pointer to the 100:th element of the string "hello", which only have six elements (don't forget the terminator).
Going out of bounds leads to undefined behavior.
Because "string" is not a std::string but a const char*, and a pointer plus a number (a character is "just" a number) uses pointer arithmetic, so after your addition, you'll get a const char* which points possibly to garbage memory after your string literal.
The second example works because in this case, s is a std::string which has a operator += for char and does not use pointer arithmetic.
The codes are not the same. In
string s="hello" + 'c';
"hello" is not a std::string. It is a string literal and has the type of const char[N]. When you add a character to it to the array decays to a pointer and you are doing pointer arithmetic. That arithmetic is going past the end of the string literal so it is undefined behavior.
In order to get the first code to act like the second example you need to make "hello" a string. You can use a user defined literal for std::string like
string s = "hello"s + 'c';
or just use a constructor call like
string s = std::string("hello") + 'c';
The expression "hello" + 'c'; is adding a char type to a const char[6] type, with an obscure result. Formally the first argument decays to a const char* pointer, and c is added to that pointer using the normal rules of pointer arithmetic. The behaviour is probably undefined, since the numeric value of c is, in all encodings I've ever come across, a value greater than 6, so you end up attempting to index an element outside the const char array "hello".
In the second version, you are exploiting the overloaded += operator of the std::string class taking a char as an argument, and the character c is concatenated to that string.
"hello" + 'c' gives a pointer past the end of "hello" (e.g. assuming an ASCII character set, 'c' has the numeric value 99, and "hello" + 99 gives a pointer to a memory location that is 99 characters past the 'h' in "hello").
Using such a pointer to initialise an std::string gives undefined behaviour.
The "CODE 2" works std::string has an operator+=() that accepts a char, and appends it to the end of the string.

C++, char* string modification [duplicate]

This question already has answers here:
Program crashes when trying to set a character of a char array
(5 answers)
Closed 5 years ago.
I am new to C++.
I have a program:
#include <iostream>
int main()
{
char* str = "Test";
*str = 'S';
}
The question is, why *str = 'S' crashes the program?
As far as I know str must be pointing to the first character of the string (well, char array), so in theory I should be able to modify it.
Is it because the memory is read-only for defined constant values?
I am using gcc 5.3.0.
why *str = 'S' crashes the program?
Because you're not allowed to modify string literals. The C++ standard allows them to be stored in read-only memory.
In fact, if you enable compiler warnings, you get:
prog.cc:5:16: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
char* str = "Test";
^~~~~~
Always use const char* when pointing to string literals: