Chinaunix

标题: [悬赏] [请教] C程序, 反斜杠 \ 作为命令行参数,会被当做转义符还是字符反斜杠 [打印本页]

作者: nine8    时间: 2010-06-22 01:05
标题: [悬赏] [请教] C程序, 反斜杠 \ 作为命令行参数,会被当做转义符还是字符反斜杠
本帖最后由 nine8 于 2010-06-22 01:19 编辑

请教下, 当 反斜杠 出现在 命令参数中时, 会被当做转义符还是 字符 '\\' ,

通过几个小程序的测试,发现似乎会被当做转义符,不知道是什么原因, 如:

  tt aaa\bbb

----------------------------------------------------------------------------------
[1] . 只会把 \当做转义符来处理, 为什么不是当做 字符 反斜杠呢?

[2] . argv 指向字符串, 那么 \ 为什么不是 字符串中的一个字符呢?


[3] . 另外, 单一的转义符有代表什么含义? 似乎没法在C中实现单一输出转义符 \ 吧, 不知道这种获取参数中转义符是如何编写的呢?

[4].  如何编写C,才使得不把命令行参数中出现的转义符\当做转义符,而是直接当做字符 \ ?


还请大家指教
作者: 没本    时间: 2010-06-22 01:05
本帖最后由 没本 于 2010-06-23 01:58 编辑

你显然还没把sh/bash的文法和C文法区分清楚。你的命令行是sh/bash文法,argv拿到的就是按C文法处理了。在sh/bash文法里面,\a是无效的,所以\被忽略了。参见:
http://www.gnu.org/software/bash ... ml#Escape-Character

  1. 3.1.2.1 Escape Character

  2. A non-quoted backslash ‘\’ is the Bash escape character. It preserves the literal value of the next character that follows, with the exception of newline. If a \newline pair appears, and the backslash itself is not quoted, the \newline is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).
复制代码
另外bash还提供了一个语法(注意要用$'带反斜杠字符串'):
http://www.gnu.org/software/bash ... #ANSI_002dC-Quoting

  1. 3.1.2.4 ANSI-C Quoting

  2. Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows:

  3. \a
  4. alert (bell)
  5. \b
  6. backspace
  7. \e
  8. \E
  9. an escape character (not ANSI C)
  10. \f
  11. form feed
  12. \n
  13. newline
  14. \r
  15. carriage return
  16. \t
  17. horizontal tab
  18. \v
  19. vertical tab
  20. \\
  21. backslash
  22. \'
  23. single quote
  24. \"
  25. double quote
  26. \nnn
  27. the eight-bit character whose value is the octal value nnn (one to three digits)
  28. \xHH
  29. the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
  30. \cx
  31. a control-x character
  32. The expanded result is single-quoted, as if the dollar sign had not been present.
复制代码

作者: 没本    时间: 2010-06-22 02:30
1. 这个与C无关,命令行的语法这么规定的,方便如文件名带空格作为参数等特殊情况的表示。
2. argv收到的已经是命令行shell处理并且传入的了,所以反斜杠转义已经完成,得到的是转义之后的结果。
3. 从命令行参数中获得在C字符串表达的\,直接在命令行用\\就可以了。
4. 你可以预处理一遍啊,比如实现一个函数pre_translate( argv[1], out_arg, &out_len ),输出到out_arg,看到\就转成\\;还有一个办法是命令行传入时,直接写成\\\\。
作者: hellioncu    时间: 2010-06-22 08:54
LS在中国么?2:30还在回帖{:3_186:}
作者: rain_fish    时间: 2010-06-22 10:03
看球的吧。。。
作者: rain_fish    时间: 2010-06-22 10:03
lz一点发帖,都是球迷啊。。。
作者: star1983653    时间: 2010-06-22 10:53
argv里的'\'都是处理好的,不用在'\\'转义了。
作者: 狗气球    时间: 2010-06-22 11:47
本帖最后由 狗气球 于 2010-06-22 11:56 编辑

转义符是解析字符串的时候起作用的。

反斜杠刚好既是C语言字符串中的转义符,也是楼主使用的shell的命令行转义符。结果搞混了。这个问题和C语言转义符没关系。

键盘输入-->(shell转义)-->传给程序的命令行参数(argv[])

****
[1] . 只会把 \当做转义符来处理, 为什么不是当做 字符 反斜杠呢?
    这个取决于你用的shell,你用的shell把反斜杠当做转义符。假如你像我现在在用windowsXP的cmd命令行,你会发现它不认为\是转义符。

[2] . argv 指向字符串, 那么 \ 为什么不是 字符串中的一个字符呢?
    因为命令行输入的单个\被shell当做转义符,没有被解释为\,所以你的程序也就没有得到你期望的\。

[3] . 另外, 单一的转义符有代表什么含义? 似乎没法在C中实现单一输出转义符 \ 吧, 不知道这种获取参数中转义符是如何编写的呢?
    单一的转义符应该不代表什么意义。
    C语言要输出‘\’没什么特别的,这本来就是个可打印字符,和'a','b'一样。
    但是,对C编译器来说,\是''和""中的转义符,为了表示真正的\字符,你只能用\\。例如'\\'代表一个反斜杠字符。"aa\\bb"代表字符串aa\bb。

[4].  如何编写C,才使得不把命令行参数中出现的转义符\当做转义符,而是直接当做字符 \ ?
    这个问题不是问题。命令行参数中的\转义符是shell决定的,和你的C程序无关。
作者: nine8    时间: 2010-06-22 21:38
  1. 1 #include <stdio.h>
  2.       2
  3.       3
  4.       4 int main(int argc, char *argv[]) {
  5.       5
  6.       6     argv++;
  7.       7     if (**argv == '\a') {
  8.       8         printf("got it \n");
  9.       9     }
  10.      10     else if(**argv == '\\') {
  11.      11         printf("got escape\n");
  12.      12     }
  13.      13     else {
  14.      14         printf("no escape\n");
  15.      15         putchar(**argv);
  16.      16     }
  17.      17
  18.      18     return 0;
  19.      19
  20.      20 }
复制代码
如上程序,

当我执行,  tt  \a, 结果却是 "no escape",然后输出 a, 也就是没有把 \a当做一个字符,而是把其\和a当做俩个处理,\被忽略

而我执行  tt \\, 结果却是 "got escaoe", 也就是说把 \\作为反斜杠字符了,

这是为什么?难道只会对 \\转义, 其他的都不行?

按照大家上面提到的似乎不好解释这个 , 还请大家指教
作者: nine8    时间: 2010-06-23 01:16

作者: nine8    时间: 2010-06-23 22:50
恩,原来如此,原来shell中的转义字符与C的不一样呀,原来以为都一样

不过我用的是csh, csh接近c的语法, 不知道 csh是不是也与bash转义字符一样呢?

有没有可能csh的转义与C一样? csh好像不是GNU里的,不知道哪可以找到其像上面bash对应的文档呢?
作者: 没本    时间: 2010-06-24 04:50
http://linux.die.net/man/1/csh
http://linux.die.net/man/1/tcsh
作者: nine8    时间: 2010-06-24 23:27
呵呵,非常感谢!
作者: nine8    时间: 2010-06-24 23:29
谢谢,没本,和狗气球

CU为什么不能同时给多人评分呢
作者: brynx    时间: 2010-06-25 11:37
{:3_189:}学习
作者: rrz214    时间: 2010-06-25 21:17
两个有一个直接是本来的意思,一个的话就是转义符吧




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2