2

I want to supply escape characters for my C program as command line arguments:

#include <cstring>
#include <cstdio>
int main(int argc,char**argv){
  const char *str1 = "\t";
  const char *str2 = argv[1];
  fprintf(stderr,"str1:%s:\nstr2:%s:\n",str1,str2);
  return 0;
}

When running this it gives:

/a.out "\t"
str1:   :
str2:\t:

So it looks like my \t is being interpreted as slash t instead of tab

Is there an easy solution for this, or do I have to check for every escape charechter I want my program to handle? Something like this?:

char *truetab="\t";
if(argv[1][0]=='\\' && argv[1][1]=='t')
   res = truetab;

Thanks.

monkeyking
  • 6,118
  • 20
  • 56
  • 76
  • What should the output be? Also, I think that escape sequences are determined at compile time and replaced with the binary constant. So you can either do your last approach, or you can input the constant. You could make an `std::map` that maps the escape character `\t` to the string ` ` (a tab). I think that that might be your only option. – Linuxios Mar 02 '12 at 15:53
  • 3
    Does this need to be handled inside your program? `/a.out` suggests that you're on *nix; if you're running this from Bash, you can just write `/a.out $'\t'` and let Bash process the escape-sequence for you. – ruakh Mar 02 '12 at 15:58
  • 1
    possible duplicate of [Convert string with explicit escape sequence into relative character](http://stackoverflow.com/questions/5612182/convert-string-with-explicit-escape-sequence-into-relative-character) – ruakh Mar 02 '12 at 15:59
  • Why not: `./a.out ""` – Martin York Mar 02 '12 at 17:23
  • What is the operating system and command-line interpreter that you are using? – Robᵩ Mar 02 '12 at 18:21

2 Answers2

1

Unfortunately, you need to do it manually: processing escape sequences is compiler's job, by the time the "hello\tworld" constant ends up in the area of string constants in the compiled code, the \t is already replaced by the ASCII code 9 (TAB). It should not be that difficult - in fact, it's an exercise number 3.2 of the classic K&R book:

Exercise 3-2. Write a function escape(s,t) that converts characters like newline and tab into visible escape sequences like \n and \t as it copies the string t to s. Use a switch. Write a function for the other direction as well, converting escape sequences into the real characters.

Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
  • In C++, I would do this with an `std::map`, not a `switch`. – Linuxios Mar 02 '12 at 16:08
  • @Linux_iOS.rb.cpp.c.lisp.m.sh I would too, but since the question is double-tagged as C/C++, I decided to stay on the safe side. I referenced K&R's exercise only to stress that the task is doable even by the beginners. – Sergey Kalinichenko Mar 02 '12 at 16:12
  • 1
    @Linux_iOS.rb.cpp.c.lisp.m.sh The K&R book predates C++ and STL, so it is understandable that it should not use such latter additions. Also, a map is quite heavyweight for switching out just a few (8 at the most?) characters. – Edwin Buck Mar 02 '12 at 16:13
  • 2
    @Linux_iOS.rb.cpp.c.lisp.m.sh: I'd be impressed if you could somehow make a `std::map` version that's either easier to read or has better performance than a `switch` version. – Dietrich Epp Mar 02 '12 at 16:17
  • @DietrichEpp, @EdwinBuck, @dasblikenlight: I know that K&R predated STL, and you are completely right to stay on the safe side. I suggested a `map` so that you could add new sequences easily and dynamically. I'm used to dynamic languages and I haven't exactly gotten used to the C/C++ optimization style. I usually prefer extendable structure to speed when the difference is not important. – Linuxios Mar 02 '12 at 16:20
  • 2
    @Linux_iOS.rb.cpp.c.lisp.m.sh: The `std::map` lets you insert sequences dynamically, but that's not something you'd ever want. The cost is that you need to initialize the `std::map` before you use it, and then you need to decide if it's global and worry about thread-safe initialization, or you decide it's local and every time the function is called you do a bunch of heap allocations. It sounds like a mess all around, where the `switch` is very, very easy to read and has none of those problems. – Dietrich Epp Mar 02 '12 at 16:36
  • @DietrichEpp: Good point. In Ruby, I'd always use a map, but that isn't the way of C/C++. Thank you for the insights as to its downfalls. – Linuxios Mar 02 '12 at 16:38
1

If you are using bash in linux, you can press Ctrl+V and hit tab, and quote it with '', you can pass almost any escape character like esc

type this:

./a.out 'Ctrl+v tab'

BTW, I don't know which software provides this functionality, maybe all unix-like terminal can do it

Aliaksei Kliuchnikau
  • 13,099
  • 4
  • 52
  • 66