Stringizing operator - c

How does the following code compile correctly,
#include <stdio.h>
#define stringer( x ) printf_s( #x "\n" )
int main() {
stringer( "In quotes when printed to the screen" );
}
isn't it supposed to get expanded into
printf_s(""In quotes when printed to the screen""\n");
which is an error as there are nested double quotes in printf_s??

No, the # operator handles character string literals specially. It must \ escape each " in a character string literal that is passed to it. The correct expansion is:
printf_s( "\"In quotes when printed to the screen\"" "\n" );

No, it's expanded into
printf_s("\"In quotes when printed to the screen\"" "\n");
which will finally be
printf_s("\"In quotes when printed to the screen\"\n");
and should print
"In quotes when printed to the screen"

In C, adjacent string literals are concatenated:
Adjacent string literals are concatenated at compile time; this allows long strings to be split over multiple lines, and also allows string literals resulting from C preprocessor defines and macros to be appended to strings at compile time:

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.

\\\ prints just one backslash?

In C, on mentioning three backslashes, like so:
#include <stdio.h>
int main() {
printf(" \\\ ");
}
prints out just one backslash in the output. Why and how does this work?
That sequence is:
A space
A double backslash, which encodes a single backslash in the runtime string
A backslash followed by a space, which is not a standard escape sequence and should give you a diagnostic
The C11 draft says (in note 77):
The semantics of these characters were discussed in 5.2.2. If any other
character follows a backslash, the result is not a token and a diagnostic is
required.
On godbolt.org I got:
<source>:8:14: warning: unknown escape sequence '\ ' [-Wunknown-escape-sequence]
So you seem to be using a non-conforming compiler, which chooses to implement undefined backslash sequences by just letting the character through.
That is printing:
space
slash
escaped space
The 3rd slash is being interpreted as "slash space"
C11; 6.4.4.4 Character constants:
The double-quote " and question-mark ? are representable either by themselves or by the
escape sequences \" and \?, respectively, but the single-quote ' and the backslash \
shall be represented, respectively, by the escape sequences \' and \\.
So, To represent a single backslash, it’s necessary to place double backslashes \\ in the source code. To print two \\ you need four backslash \\\\. In your code extra \ is a space character, which isn't valid.
It is indeed a very simple operation in c. A \ is just a escape sequences. Hence below statement will print two slash.
printf(" \\\\ ");
For example some characters in c are represented with a slash like end of a line character \n or end of a string character \0 etc. But if you want to print such a character as it is what will you do? Hence you need to add a escape sequence character in front of it:
printf("\\n"); // will print \n
But
printf("\n"); // will print end of character hence you don't see anything in output

Why do '?' and '\?' give the same output in C?

In C, why do these two pieces of code give the same output?
#include<stdio.h>
int main(void)
{
const char c='\?';
printf("%c",c);
}
and
#include<stdio.h>
int main(void)
{
const char c='?';
printf("%c",c);
}
I understand that a backslash is used to make quotes (" or ') and a backslash obvious to the compiler when we use printf(), but why does this work for the '?'?
\? is an escape sequence exactly equivalent to ?, and is used to escape trigraphs:
#include <stdio.h>
int main(void) {
printf("%s %s", "??=", "?\?="); // output is # ??=
}
Quoting C11, chapter §6.4.4.4p4
The double-quote " and question-mark ? are representable either by themselves or by the escape sequences \" and \?, respectively, but ... .
Emphasis mine
So the escape sequence \? is treated the same as ?.
Because '\?' is a valid escape code, and is equal to a question-mark.
when you're defining a char or string the compiler parses backslash in that char or string as an escape sequence.
**
the simple answer of your question is
\? means ?. instead of using \? you can using ? .
\? is escape representation and ? is character representation means both are same.
i have linked a image so that you understand it more easily..
**
"click here to see the image " --> in this image you need to find \? in Escape character

Printing space with a macro and # operator in C

I was working with macros and wrote one like this:
#define STR(name) #name
I meant STR() to stringise whatever that was given to it as argument and it seemed to be working.
printf( STR(Hello) )
gave the output as expected:
Hello
So did
printf( STR(Hello world) );
printf( STR(String) STR(ise) );
which gave
Hello world
Stringise
But when I tried to use STR() to print only a space, it just didn’t work.
printf( STR(Hello) STR( ) STR(World) ); //There’s a space between the parenthesis of the second STR
Gave the output:
HelloWorld
Here the STR( ) is ignored.
Why is this? Is there a way around it using while still sticking to macros with only a space as argument?
I was just wondering if this was possible.
It is not possible for the stringification to result into a single space. The semantics of the # operator are detailed in C11 6.10.3.2p2:
If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument. Each occurrence of white space between the argument's preprocessing tokens becomes a single space character in the character string literal. White space before the first preprocessing token and after the last preprocessing token composing the argument is deleted. [...] The character string literal corresponding to an empty argument is "". [...].
Thus, as the space is not a preprocessing token, and leading and trailing space is deleted, it is impossible for the stringification operator to create a resulting string literal that just contains a single space. As you've noticed, STR( ) would pass an empty argument to the macro, and this would be stringified into ""; likewise
STR( Hello
World
)
would be expanded into "Hello World"; i.e. each occurrence of white space would become a single space character, and the preceding and trailing whitespace would be deleted.
However, while it is not possible to stringify a single space, it is possible to achieve the required output. The preprocessor concatenates consecutive string literal tokens into one, so "Hello" " " "World" would be converted to `"Hello world"; therefore
printf(STR(Hello) " " STR(World));
would after macro expansion be expanded to
printf("Hello" " " "World");
and thereafter to
printf("Hello World");

Using printf without having to escape double quotes?

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++

Resources