I almost reached end of my code, after a lot of search I didn't find solution no where, I want to supply escape sequence like '\t', '\n' to my program like how awk
and perl
program takes, and finally I want to use them as printf or sprintf format string
This is what I tried so far, please note I need to have variable delim and rs should be pointer.
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
int main (int argc, char **argv)
{
int c;
char *delim = ",", *rs = "\n\r";
while (1)
{
static struct option long_options[] =
{
{"delim", required_argument, 0, 'd'},
{"row_sep", required_argument, 0, 'r'},
{0, 0, 0, 0}
};
int option_index = 0;
c = getopt_long (argc, argv, "df",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
if (long_options[option_index].flag != 0)
break;
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case 'd':
delim = optarg;
break;
case 'r':
rs = optarg;
break;
case '?':
break;
default:
abort ();
}
}
/* Print any remaining command line arguments (not options). */
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
putchar ('\n');
}
/* Test input argument */
printf("This is test%ssome text%s",delim,rs);
exit (0);
}
When I compile and execute I get output like this
$ gcc argument.c
$ ./a.out --delim="\t"
This is test\tsome text
$ ./a.out --delim="\t" --row_sep="\n"
This is test\tsome text\n
I expect it to print tab and newline instead of '\t' and '\n' as original
Kindly someone help me.
Some code somewhere has to translate backslash-t and backslash-n into tab and newline. You can have the shell do it (if it is Bash or supports ANSI C quoting):
./a.out --delim=$'\t'
./a.out --delim=$'\t' --row_sep=$'\n'
Or use the printf
command (distinct from, though related to, the printf()
function); this avoids using any Bashisms:
./a.out --delim="$(printf '\t')"
./a.out --delim="$(printf '\t')" --row_sep="$(printf '\n')"
Or, indeed, you can simply type the characters at the command line. Entering tab needs you to type Control-VControl-I to avoid filename completion.
$ ./a.out --delim='^V^I'
$ ./a.out --delim='^V^I' --row_sep='
> '
This is less clear, though; I'd use one of the previous two mechanisms in preference.
Or you can do it in your program. That's a little harder, but not much. I have a rather comprehensive function, cstrlit_chr()
that does most of that job (it doesn't handle Unicode escapes like \u0123
or \U00012345
), but it isn't standard and it is in a file that's 238 lines long with the comments and test code, etc (just over 100 non-blank, non-comment lines of C code in the function, which could be compressed a bit if I wanted to spend the time on it), so it's a bit big to add it here.
Can you please show me
cstrlit_chr()
example for the same?
The header documenting the interface says:
/* Convert C String Literal in (str..end] (excluding surrounding quotes) */
/* to string, returning length of string, or -1 if conversion error, or */
/* -2 if there is not enough room for the output */
extern int cstrlit_str(const char *str, const char *end, char *buffer, size_t buflen);
/* Convert C Character Literal in (str..end] (excluding surrounding quotes) */
/* to character, returning converted char or -1 if string is invalid. */
/* If non-null, eptr is set to first non-converted (or non-convertible) character */
extern int cstrlit_chr(const char *str, const char *end, char const ** const eptr);
/* Convert character to C Character Literal. */
/* buffer[0] = '\0' if there isn't enough room in buffer */
extern void chr_cstrlit(unsigned char c, char *buffer, size_t buflen);
/* Convert string to C String Literal */
extern void str_cstrlit(const char *str, char *buffer, size_t buflen);
So, cstrlit_chr()
is one of a set of four functions. However, it is pretty easy to use:
const char *endptr;
int c = cstrlit_char(argv[i], argv[i]+strlen(argv[i]), &endptr);
If argv[i]
contains backslash and t
, then c
will be assigned the value of '\t'
(which is usually control-I or 9). If it contains backslash and n
, then c
will be assigned the value of '\n'
(which is usually control-J or 10).
The value in endptr
tells you what's the next character to be interpreted.