C语言 如何打印一个两行中间有'\n'的字符串?

myzjeezk  于 2023-03-22  发布在  其他
关注(0)|答案(3)|浏览(141)

我遇到了一个问题。我需要用C语言创建一个程序,它以字符串为参数并打印它。问题是:如果我把\n\t放在中间,我的程序将其打印为nt。但我需要将它们打印为新的一行或表格。程序必须理解\n\t。我如何才能做到这一点?
预期结果:

$> ./my_program aaa\nbbb
aaa
bbb
$>

我的(错误)结果:

$> ./my_program aaa\nbbb
aaanbbb
$>

这是我的准则

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{   
    int i = 0;
    //printf("%s", argv[1]); - that doesn't works also :(
    while (argv[1][i] != '\0') {
        printf("%c", argv[1][i]);
        i++;
    }
    return (0); 
}

我尝试使用printfwrite函数。我尝试将其打印为字符串或按字符...

7lrncoxx

7lrncoxx1#

一旦有了一个嵌入了换行符的字符串,用两行打印出来就非常简单了--几乎任何可以打印字符串的东西都可以做到这一点。

#include <stdio.h>

int main() { 
    char const *s = "aaa\nbbb";
    printf("%s", s);
    return 0;
}

结果:

aaa
bbb

所以,你面临的问题不是打印字符串,甚至与C本身也没有任何关系。你真正的问题归结为:“how do you pass a command line parameter with an embedded newline?”幸运的是,有一种非常简单的方法可以做到这一点(至少使用bash或zsh)。让我们从一个简单的程序开始,打印出第一个命令行参数:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <string>\n", argv[0]);
        return EXIT_FAILURE;
    }
    printf("%s", argv[1]);
    return 0;
}

从这里开始,我们要做的就是如何调用程序:

./a.out aaa$'\n'bbb

结果:

aaa
bbb

这里的“技巧”是$'\n',它告诉shell“展开”\n,这样被调用的程序将看到它作为一个换行符。

cclgggtu

cclgggtu2#

您的程序一次输出一个字符的命令行参数:使用%s可获得相同的结果:

#include <stdio.h>

int main(int argc, char *argv[]) {   
    if (argc > 1)
        printf("%s", argv[1]);
    return 0; 
}

问题来自命令shell处理\字符的方式。您的shell不会将\n解释为命令行参数中的换行符,而是将其解释为引号和\本身的转义。
您可以通过以下方式引用参数,在命令行参数中传递换行符:

$> ./my_program 'aaa
bbb'
aaa
bbb
$>

或者,您可以通过编写./my_program aaa\\nbbb./my_program 'aaa\nbbb'\传递给程序,并修改程序以显式解释转义序列:

#include <stdio.h>

int print_escaped_string(const char *s) {
    int n = 0;
    while (*s != '\0') {
        unsigned char uc = *s++;
        if (uc == '\\') {
            switch (*s) {
              case '\\':             s++; break;
              case 'n': uc = '\n';   s++; break;
              case 't': uc = '\t';   s++; break;
              case 'e': uc = '\033'; s++; break;
            }
        }
        putchar(uc);
        n++;
    }
    return n;
}

int main(int argc, char **argv) {   
    for (int i = 1; i < argc; i++) {
        print_escaped_string(argv[i]);
    }
    return 0; 
}
30byixjq

30byixjq3#

要打印2个字符\n或打印2个字符\t作为换行符和制表符,请处理字符串,查找以 * 转义序列 * 开头的\
C定义了4个转义序列。

  • 简单转义序列
  • 八进制转义序列
  • 十六进制转义序列
  • 通用字符名

只看 simple-escape-sequences,C定义:' \”\?\ \a \B \f \n \r \t \v
所以除了\n \t之外,代码还可以查找所有的

int main(int argc, char *argv[]) {
  if (argc > 1) {
    const char *s = argv[1];
    while (*s != '\0') {
      if (*s == '\\') {
        s++;
        const char c[] = {'\"', '\'', '?', '\\', 'a', 'b', 'f', 'n', 'r', 't', 'v', 0};
        const char e[] = {'\"', '\'', '?', '\\', '\a', '\b', '\f', '\n', '\r', '\t', '\v', 0};
        const char *find = strchr(c, *s);
        if (find && *find) {
          putchar(e[find - c]);
        } else {
          fprintf(stderr, "Invalid escape sequence found \\%3o\n", (unsigned char) *s);
          break;
          // or perhaps look for the other 3 types of escape sequences...
        }
      } else {
        putchar(*s);
      }
      s++;
    }
  }
}

相关问题