Using printf without having to escape double quotes? - c

In C it is not normally possible to use ' for printf of a string. However, I have text which are full of double quote ", and I need to escape all of them as
printf("This is \"test\" for another \"text\"");
Is it possible to printf in a way without escaping ". I mean using another character for wrapping the string.

Not recommended, but you can use a macro:
#include <stdio.h>
#define S(x) #x
int main() {
printf(S(This "is" a string (with nesting)!\n));
}
This prints
This "is" a string (with nesting)!
Now the delimiters are balanced () characters. However, to escape single ), ", or ' characters, you have to write something like S(right paren: ) ")" S(!\n), which is quite ugly. This technique is not recommended for writing maintainable code.

No, that is not possible in the C language. There is only one syntax for string literals, and that is that they are delimited by double quotes.
The only way to write unescaped quotation marks is as character literals inside character arrays, which is uglier and more difficult to write, so there's very little reason to do so in a case like this:
char array[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ', '"'}; // etc.
printf("%s", array);

No there is not other way, the draft C99 standard in section 6.4.5 String literals has the following grammar:
string-literal:
" s-char-sequenceopt "
L" s-char-sequenceopt "

No, it's not possible in standard C.
C11 6.4.5 String literals
The same considerations apply to each element of the sequence in a string literal as if it
were in an integer character constant (for a character or UTF−8 string literal) or a wide
character constant (for a wide string literal), except that the single-quote ' is representable either by itself or by the escape sequence \', but the double-quote " shall be represented by the escape sequence \".

First of all, separate a program's requirements from the solutions to meet those requirements. Given the minimum amount of info. in this question, the requirement is to print, using C, a string that has double quotes. There are several ways to do this in C.
For example, the following code fragment:
char string[] = "This string \" has one double quote.";
printf("This string %cprints%c with %cdouble%c quotes", '"', '"', '"', '"');
printf("%s", string);
produces:
This string "prints" with "double" quotes.
This string " has one double quote.
Your application might have more requirements that you have not mentioned, but it should be possible to achieve what you want, just NOT the way you initially believe it should be done (welcome to the world of "Needs Analysis").

//R "delimiter( raw_characters )delimiter"
printf(R"SOME/\STRING");
Raw string will terminate after the first )" it sees.
Therefore, if )" is in the string, you have to add delimiter ("a" is used below)
/* Print dog without any escape. */
printf(R"a(|\_/|
|q p| /}
( 0 )"""\
|"^"` |
||_/=\\__|)a");
}
It's C++11 feature and you can find more information in
document
Simliar question have been answered escape R"()" in a raw string in C++

Related

Why does C not recognize strings across multiple lines?

(I am very new to C.)
Visual newlines seem to be unimportant in C.
For instance:
int i; int j;
is same as
int i;
int j;
and
int k = 0 ;
is same as
int
k
=
0
;
so why is
"hello
hello"
not the same as
"hello hello"
It is because a line that contains a starting quote character and not an ending quote character was more likely a typing mistake or other error than an attempt to write a string across multiple lines, so the decision was made that string literals would not span source lines, unless deliberately indicated with \ at the end of a line.
Further, when such an error occurs, the compile would be faced with reading possibly thousands of lines of code before determining there was no closing quote character (end of file was reached) or finding what was intended as an opening quote character for some other string literal and then attempting to parse the contents of that string literal as C code. In addition to burdening early compilers with limited compute resources, this could result in confusing error messages in a part of the source code far removed from the missing quote character.
This choice is effected in C 2018 6.4.5 1, which says that a string literal is " s-char-sequenceopt ", where s-char-sequence is any member of the character set except the quote character, a backslash, or a new-line character (and a string literal may also have an encoding prefix, a u8, u, U, or L before the first ").
Strings can be continued over newlines by putting a backslash immediately before the newline:
"hello \
hello"
Or (better), using string concatenation:
"hello "
"hello"
Note that the space has been carefully preserved so that these are equivalent to "hello hello" except for the line numbering in the file after the appearance.
The backslash-newline line elimination is done very early in the translation process — in phase 2 of the conceptual translation phases.
Note that there is no stripping leading blanks or anything. If you write:
printf("Some long string with maybe an integer %d in it\
and some more data on the next line\n", i);
Then the string has a sequence of (at least) 8 blanks in it between in it and and some. The count of 8 assumes that the printf() statement is aligned in the left margin; if it is indented, you'd need to add the extra white space corresponding to the indentation.
1- using double quotes for each string :
char *str = "hello "
"hello" ;
** One problem with this approach is that we need to escape specially characters such as quotation mark " itself.
2- Using - \ :
char *str = "hello \
hello" ;
** This form is a lot easier to write, we don't need to write quotation marks for each line.
We can think of a C program as a series of tokens: groups of characters that can't be split up without changing their meaning. Identifiers and keywords are tokens. So are operators like + and -, punctuation marks such as the comma
and semicolon, and string literals.
For example, the line
int i; int j;
consists of 6 tokens: int, i, ;, int, j and ;. Most of the time, and particularly in this case, the amount of space (space, tab and newline characters) is not critical. That's why the compiler will treat
int i
;int
j;
The same.
Writing
"Hello
Hello"
Is like writing
un signed
and hope that the compiler treat it as
unsigned
Just like space is not allowed between a keyword, newline character is not allowed in a string literal token. But it can be included using the newline escape '\n' when needed.
To write strings across lines use string concatenation method
"Hello"
"Hello"
Although the above method is recommended, you can also use a backslash
"Hello \
Hello"
With the backslash method, beware of the beginning space in a new line. The string will include everything in that line until it finds a closing quote or another backslash.

Separating hexadecimal escape sequences in strings

Can a string constant like "foo" "\x01" "bar" be written as a single string literal (while keeping the hexadecimal notation)? With "foo\x01bar" the escape sequence seems to be interpreted as \x01ba since I get the warning "hex escape sequence out of range."
"foo" "\x01" "bar" is a string literal.
The C standard states that a hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence. Without the explicit concatenation (which is the common workaround to this problem), the compiler parses \x01ba which is obviously out of range.
How about "foo\x01\142ar"? Is that cheating?
Another solution is to simply write the escaped character in octal, instead of hexadecimal
"foo\1bar"
and no more ambiguity...

C program to store special characters in strings

Basically, I can't figure this out, I want my C program to store the entire plaintext of a batch program then insert in a file and then run.
I finished my program, but holding the contents is my problem. How do I insert the code in a string and make it ignore ALL special characters like %s \ etc?
You have to escape special characters with a \, you can escape backslash itself with another backslash (i.e. \\).
As Ian previously mentioned, you can escape characters that aren't allowed in normal C strings with \; for instance, newline becomes \n, double-quote becomes \", and backslash becomes \\.
If you're unable or unwilling to do this for whatever reason, then you may be out of luck if you're solution must be in C. However, if you're willing to switch to C++, then you can use raw strings:
const char* s1 = R"foo(
Hello
World
)foo";
This is equivalent to
const char* s2 = "\nHello\nWorld\n";
A raw string must begin with R" followed by an arbitrary delimiter (made of any source character but parentheses, backslash and spaces; can be empty; and at most 16 characters long), then (, and must end with ) followed by the delimiter and ". The delimiter must be chosen such that the termination substring (), delimiter, ") does not appear within the string.

Writing printf(#"") with multiple line string

Is it possible to write something like this:
printf(#"
-
-
-
-
");
I can do it in C#, but can't in C. It gives me an error in CodeBlocks. Am I allowed to do such ?
Error message: error: stray '#' in program.
No. That syntax doesn't exist in C.
If you want a multiple-line string, write it as multiple double-quoted strings with no other tokens in between them. They will be combined.
printf(
"some string"
"more of the string"
"even more of the string"
);
(You will, of course, need to add a \n at the end of each line if that's what you want.)
No that's not a syntax that C understands, C doesn't have raw literals.
You can use \ as the last character to continue on the next line:
const char *str = "hello\n\
world";
Also, consecutive string literals will be concatenated. So you can do e.g.
const char *str = "Hello\n"
"world\n";
C#'s verbatim strings are not available in C. If you have some characters to escape, like " or \, escape them with '\', there is no there option in this language.
If you want to embed multiple lines in a string literal, you can either insert \n at the appropriate location in your string, or escape the return character as well:
printf("Here's\
a multiline\
string litteral");
Line continuation with \ at the end of the line.
printf("\
\
-\
-\
-\
-\
");
String literals in C may not contain newlines. You have two workarounds:
Use implicit string concatenation (done by the compiler).
printf("The quick brown"
" fox jumps over"
" the sleazy dog.");
Escape the newline by placing a backslash in front of it.
printf("The quick brown\
fox jumps over\
the sleazy dog.");
Personally, I prefer the first form since the second looks ugly (my opinion) and forces you to ruin your code indentation.
In either case, the string will simply not contain the newlines. So if you really meant for them to be there, you'll have to add them via \n.

printf("string1""string2") is this valid C?

I was trying to figure out something when I wrote this by a mistake
printf("string1""string2");
To my surprise it compiled and produced a concatenated string output i.e
string1string2
Is this valid C?
I am using gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
Yes it is. Consecutive string literals are concatenated early in the parsing of C.
6.4.5 / 4:
In translation phase 6, the multibyte character sequences specified by any sequence of adjacent character and wide string literal tokens are concatenated into a single multibyte character sequence. If any of the tokens are wide string literal tokens, the resulting multibyte character sequence is treated as a wide string literal; otherwise, it is treated as a character string literal.
Yes, and it can be very useful to concatenate string constants at compile-time.
#define VERSION "1.0"
#define COMPANY "Trivial Software"
printf("hello world: v. " VERSION " copyright (c) " COMPANY);
or
puts(
"blah blah blah\n"
"blah blah blah\n"
"blah blah blah\n"
"blah blah blah\n"
);
Yes, it is valid and has been part of the C language for a very long time (if not since the beginning). The concatenation is done at compile time.
As other said, yes, it is valid. I only wanted to add that it is really useful to input long strings that fill several lines. You don't have to mess with \ to indicate the string continues, and don't wanting to add a carriage return too, so you just write:
"very long string "
"that continues over here"
(watch out the spaces at the end of each string, it is a common mistake. In this case, "string" and "that" would be joint.)

Resources