Why can't I write to a string literal while I *can* write to a string object?
Because "Hello"
creates a const char[]. This decays to a const char*
not a char*
. In C++ string literals are read-only. You've created a pointer to such a literal and are trying to write to it.
But when you do
string s1 = "hello";
You copy the const char* "hello" into s1
. The difference being in the first example s1
points to read-only "hello" and in the second example read-only "hello" is copied into non-const s1
, allowing you to access the elements in the copied string to do what you wish with them.
If you want to do the same with a char* you need to allocate space for char data and copy hello into it
char hello[] = "hello"; // creates a char array big enough to hold "hello"
hello[0] = 'w'; // writes to the 0th char in the array
Why is #include string needed for string objects but not string literals?
A string literal is not a std::string
object, it's an array of const char
."This is a string literal"
has the type const char[25]
.
In most situations – including this one – an array implicitly decays into a pointer to its first element, and there is an operator<<
overload for const char*
.
It's pretty confusing that "string" means several different things in C++, but after a while (and pulling of hair and gnashing of teeth) the intended meaning will be clear from context.
Can't understand how Java string literals are implemented
15.18.1. String Concatenation Operator +
An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.
In your case,
String s1 = "hello";
String s2 ="bc";
int value = 22;
String r = s1 + s2 + value;
you will get
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ILOAD 3
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
While concatinating constant objects
String r = "hello" + "bc" + 22;
you will get
LDC "hellobc22"
ASTORE 2
When the compiler "meets" this code:
String s = s1+s2+22;
it "changes" it to:
String s = new StringBuilder().append("hello").append("bc").append(22).toString();
No. It may optimise it to
String s = new StringBuilder().append(s1).append(s2).append(value).toString();
but it can't replace s1
with "hello"
because there is no guarantee the variable will keep referring to "hello"
. The variable is not final and thus open to reassignment.
Strings are objects in Java, so why don't we use 'new' to create them?
In addition to what was already said, String literals [ie, Strings like "abcd"
but not like new String("abcd")
] in Java are interned - this means that every time you refer to "abcd", you get a reference to a single String
instance, rather than a new one each time. So you will have:
String a = "abcd";
String b = "abcd";
a == b; //True
but if you had
String a = new String("abcd");
String b = new String("abcd");
then it's possible to have
a == b; // False
(and in case anyone needs reminding, always use .equals()
to compare Strings; ==
tests for physical equality).
Interning String literals is good because they are often used more than once. For example, consider the (contrived) code:
for (int i = 0; i < 10; i++) {
System.out.println("Next iteration");
}
If we didn't have interning of Strings, "Next iteration" would need to be instantiated 10 times, whereas now it will only be instantiated once.
Why do I get a segmentation fault when writing to a char *s initialized with a string literal, but not char s[] ?
See the C FAQ, Question 1.32
Q: What is the difference between these initializations?
char a[] = "string literal";
char *p = "string literal";
My program crashes if I try to assign a new value top[i]
.A: A string literal (the formal term
for a double-quoted string in C
source) can be used in two slightly
different ways:
- As the initializer for an array of char, as in the declaration of
char a[]
, it specifies the initial values
of the characters in that array (and,
if necessary, its size).- Anywhere else, it turns into an unnamed, static array of characters,
and this unnamed array may be stored
in read-only memory, and which
therefore cannot necessarily be
modified. In an expression context,
the array is converted at once to a
pointer, as usual (see section 6), so
the second declaration initializes p
to point to the unnamed array's first
element.
Some compilers have a switch
controlling whether string literals
are writable or not (for compiling old
code), and some may have options to
cause string literals to be formally
treated as arrays of const char (for
better error catching).
In Java, is there a way to write a string literal without having to escape quotes?
The answer is no, and the proof resides in the Java Language Specification:
StringLiteral:
"StringCharacters"
StringCharacters:
StringCharacter
| StringCharacters StringCharacter
StringCharacter:
InputCharacter but not " or \
| EscapeSequence
As you can see a StringLiteral
can just be bound by "
and cannot contain special character without escapes..
A side note: you can embed Groovy inside your project, this will extend the syntax of Java allowing you to use '''multi line string '''
, ' "string with single quotes" '
and also "string with ${variable}"
.
Creating multiline strings in JavaScript
Update:
ECMAScript 6 (ES6) introduces a new type of literal, namely template literals. They have many features, variable interpolation among others, but most importantly for this question, they can be multiline.
A template literal is delimited by backticks:
var html = `
<div>
<span>Some HTML here</span>
</div>
`;
(Note: I'm not advocating to use HTML in strings)
Browser support is OK, but you can use transpilers to be more compatible.
Original ES5 answer:
Javascript doesn't have a here-document syntax. You can escape the literal newline, however, which comes close:
"foo \
bar"
python: SyntaxError: EOL while scanning string literal
You are not putting a "
before the end of the line.
Use """
if you want to do this:
""" a very long string ......
....that can span multiple lines
"""
Related Topics
Does Std::Vector *Have* to Move Objects When Growing Capacity? Or, Can Allocators "Reallocate"
Tackling Class Imbalance: Scaling Contribution to Loss and Sgd
Exit() Call Inside a Function Which Should Return a Reference
How to Reliably Get an Object's Address When Operator& Is Overloaded
Nested Templates with Dependent Scope
Benefits of Ternary Operator VS. If Statement
Tmp: How to Generalize a Cartesian Product of Vectors
Workaround for Template Argument Deduction in Non-Deduced Context
Why Does VS Not Define the Alternative Tokens for Logical Operators
Warning: Format Not a String Literal and No Format Arguments
How to Detect Existence of a Class Using Sfinae
Why Stdfax.H Should Be the First Include on Mfc Applications
What Does Flushing the Buffer Mean
Can You Make Custom Operators in C++
M_Pi Works with Math.H But Not with Cmath in Visual Studio