How to convert a c string into its escaped version in c?
No, there isn't any standard function for creating the source code version of the string. But you could use the iscntrl
function to write one, or just use the switch
keyword.
But, unless your program writes out a C source file intended to be run through the compiler, you don't need to work with escaped strings. printf
doesn't process character escape sequences, only variable insertions (%d
, %s
, etc)
Specifically, the following produce the same output:
printf("\tHello World\n");
and
const char* str = "\tHello World\n";
printf(str);
and
const char* str = "\tHello World\n";
printf("%s", str);
The second one isn't a good idea, because if str
contained %
your program would produce bad output and could crash.
EDIT: For producing the source code version, there are a couple of approaches:
Simpler, but less readable output:
if (iscntrl(ch) || ch == '\\' || ch == '\"' || ch == '\'') {
fprintf(outf, "\\%03o", ch);
}
else
fputc(ch, outf);
More readable results:
switch (ch) {
case '\"':
fputs("\\\"", outf);
break;
case '\'':
fputs("\\\'", outf);
break;
case '\\':
fputs("\\\\", outf);
break;
case '\a':
fputs("\\a", outf);
break;
case '\b':
fputs("\\b", outf);
break;
case '\n':
fputs("\\n", outf);
break;
case '\t':
fputs("\\t", outf);
break;
// and so on
default:
if (iscntrl(ch)) fprintf(outf, "\\%03o", ch);
else fputc(ch, outf);
}
Can I convert a C# string value to an escaped string literal?
There's a method for this in Roslyn's Microsoft.CodeAnalysis.CSharp package on NuGet:
private static string ToLiteral(string valueTextForCompiler)
{
return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(valueTextForCompiler, false);
}
Obviously, this didn't exist at the time of the original question, but it might help people who end up here from Google Search.
Escaping characters in C
You need to special case the replacement of '\n'
to '\\'
+ 'n'
etc.
There is no need to make a local copy of src
to scan for special characters. You can simplify the code this way:
char *escapeChars(const char *src) {
int i, j;
char *pw;
for (i = j = 0; src[i] != '\0'; i++) {
if (src[i] == '\n' || src[i] == '\t' ||
src[i] == '\\' || src[i] == '\"') {
j++;
}
}
pw = malloc(i + j + 1);
for (i = j = 0; src[i] != '\0'; i++) {
switch (src[i]) {
case '\n': pw[i+j] = '\\'; pw[i+j+1] = 'n'; j++; break;
case '\t': pw[i+j] = '\\'; pw[i+j+1] = 't'; j++; break;
case '\\': pw[i+j] = '\\'; pw[i+j+1] = '\\'; j++; break;
case '\"': pw[i+j] = '\\'; pw[i+j+1] = '\"'; j++; break;
default: pw[i+j] = src[i]; break;
}
}
pw[i+j] = '\0';
return pw;
}
Note that you should also escape some other characters: '\r'
, and the non printing or non portable characters in the range 1 to 31 and 127 to 255 for ASCII. Escaping these as octal sequences is more work but manageable at your skill level.
Convert characters in a c string to their escape sequences
There's no built-in function for this, but you could whip one up:
/* Expands escape sequences within a C-string
*
* src must be a C-string with a NUL terminator
*
* dest should be long enough to store the resulting expanded
* string. A string of size 2 * strlen(src) + 1 will always be sufficient
*
* NUL characters are not expanded to \0 (otherwise how would we know when
* the input string ends?)
*/
void expand_escapes(char* dest, const char* src)
{
char c;
while (c = *(src++)) {
switch(c) {
case '\a':
*(dest++) = '\\';
*(dest++) = 'a';
break;
case '\b':
*(dest++) = '\\';
*(dest++) = 'b';
break;
case '\t':
*(dest++) = '\\';
*(dest++) = 't';
break;
case '\n':
*(dest++) = '\\';
*(dest++) = 'n';
break;
case '\v':
*(dest++) = '\\';
*(dest++) = 'v';
break;
case '\f':
*(dest++) = '\\';
*(dest++) = 'f';
break;
case '\r':
*(dest++) = '\\';
*(dest++) = 'r';
break;
case '\\':
*(dest++) = '\\';
*(dest++) = '\\';
break;
case '\"':
*(dest++) = '\\';
*(dest++) = '\"';
break;
default:
*(dest++) = c;
}
}
*dest = '\0'; /* Ensure nul terminator */
}
Note that I've left out translation of an escape sequence for the "escape" character, since this isn't standardized in C (some compilers use \e
and others use \x
). You can add in whichever applies to you.
If you want a function that allocates your destination buffer for you:
/* Returned buffer may be up to twice as large as necessary */
char* expand_escapes_alloc(const char* src)
{
char* dest = malloc(2 * strlen(src) + 1);
expand_escapes(dest, src);
return dest;
}
standard c library for escaping a string
If you were writing GPL stuff you might use http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/quotearg.c;hb=HEAD
How to escape special characters in a char* string in C
It is still unclear why you think the string has "dangerous" chars, but if you want to escape some of them:
const char *str = "my dangerous";
const char *ooh = "aeoui\\";
char buf[BIG_ENOUGH];
size_t bp = 0;
for (size_t sp = 0; str[sp]; sp++) {
if (strchr(ooh, str[sp])) buf[bp++] = '\\';
buf[bp++] = str[sp];
}
buf[bp] = 0;
Is there a way to escape the C string null terminator character?
Note that a "string" with an embedded NUL is no longer a string. You cannot safely use it as an argument to functions declared in <string.h>
, for example
char embeddednul[] = "zero\0one\0two\0"; // embeddednul[12] = embeddednul[13] = 0
printf("len: %d\n", strlen(embeddednul)); // 4??
char tmp[1000] = {0};
strcpy(tmp, embeddednul); // copies 'z', 'e', 'r', 'o', and 0
char *p = embeddednul;
while (*p) {
while (*p) putchar(*p++); // prints zero
putchar('\n'); // then one
p++; // then two
}
Related Topics
How to Use a Mask to Iterate Files in a Directory with Boost
How to Declare a Vector of Atomic in C++
What Is the Precision of Long Double in C++
Blending Does Not Remove Seams in Opencv
Warning: Format Not a String Literal and No Format Arguments
How to Set File Permissions (Cross Platform) in C++
How to Delete an Element from a Vector While Looping Over It
C++ String to Double Conversion
How to Combine Several C/C++ Libraries into One
How to Get a List of Video Capture Devices (Web Cameras) on Linux ( Ubuntu )? (C/C++)
How to Detect Double Precision Floating Point Overflow and Underflow
Trouble with Inheritance of Operator= in C++
Copy Constructor Is Not Inherited
How to Use Openssl's Sha256 Functions
Repeated Multiple Definition Errors from Including Same Header in Multiple Cpps