C 为什么赢了';我的程序不能正确地接受另一个程序的管道输出吗?

C 为什么赢了';我的程序不能正确地接受另一个程序的管道输出吗?,c,unix,command-line,pipe,argc,posix,C,Unix,Command Line,Pipe,Argc,Posix,我有一个用3.C文件编译的C程序。从本质上说,该程序根据我在main中定义的x和y大小输入,将正方形打印到标准输出。相关代码如下: void rush(int x, int y); int main(void) { rush(3, 3); return (0); } 运行main的可执行文件,如下所示: ./a.out 提供以下信息: o-o | | o-o o---o | | | | | | o---o 将传递给rush函数的参数更改为(5,

我有一个用3.C文件编译的C程序。从本质上说,该程序根据我在main中定义的x和y大小输入,将正方形打印到标准输出。相关代码如下:

void    rush(int x, int y);

int     main(void)
{
    rush(3, 3);
    return (0);
}
运行main的可执行文件,如下所示:

./a.out
提供以下信息:

o-o
| |
o-o
o---o
|   |
|   |
|   |
o---o
将传递给rush函数的参数更改为(5,5),得到以下结果:

o-o
| |
o-o
o---o
|   |
|   |
|   |
o---o
你明白了。每行由一个分隔符分隔,\n该分隔符允许函数打印正确的下一行。我有另一个测试程序,它是一个简单的编译的main,它只打印ARGC的值,因为我想测试这样一个输入将给出的管道的行为。第二个主程序是这样的:

#include <stdio.h>

int     main(int argc, char **argv)
{
    printf("argc value is: %d\n", argc);
    return (0);
}
我得到以下输出:

argc value is: 1
这对我来说一开始没什么意义,但后来我记得这是因为有些命令需要xargs正确地接受来自stdin的输入。使用带有(5,5)的xargs作为主菜单中的输入:

./a.out | xargs ./test
导致:

argc value is: 9

因此我有两个问题。有没有一种方法不需要xargs就可以做到这一点,并且可以在c文件中完成?知道测试文件的输入,为什么argc==9?程序如何将该格式的字符串分离出来并决定放入数组中的内容?

这是因为xargs接受整个输入(所有行,而不仅仅是一行),并用空格字符将其拆分。因此,测试代码得到的参数是(您可以自己打印以进行调试):

  • /测试
  • o--o
  • |
  • |
  • |
  • |
  • |
  • |
  • o--o

  • 如果您想从stdin读取而不是解析参数,请使用
    cin>>string\u variable

    这会很长,所以请喝上您最喜欢的饮料。休息后不要直接跳到答案

    首先,检查提供给程序的命令行参数,例如args.c

    #包括
    #包括
    int main(int argc,char*argv[])
    {
    int i;
    printf(“argc=%d\n”,argc);
    对于(i=0;i
    用你最喜欢的C编译器编译;我使用gcc:

    gcc-Wall-O2 args.c-o args
    
    如果你跑了,说

    /args一二
    
    它将输出

    argc=3
    argv[0]=“/args”
    argv[1]=“一”
    argv[2]=“两个”
    
    所有unix都有一个命令行实用程序或shell内置的
    printf
    ,其工作原理与C
    printf()标准库函数类似。例如,我们可以跑步

    printf'你好,世界\n第二行\n第三行\n'
    
    我们拭目以待

    你好,世界!
    第二线
    第三行
    
    现在,如果我们用管道连接这两个

    printf'你好,世界\n第二行\n第三行\n'|/args
    
    我们得到

    argc=1
    argv[0]=“/args”
    
    因为没有
    /args
    的参数,并且上面的args.c完全忽略标准输入

    实用程序命令读取输入,然后作为命令执行自己的命令行参数,将读取的输入添加为附加参数。它也是高度可配置的。如果你跑

    printf'你好,世界\n第二行\n第三行\n'| xargs./args
    
    你会得到

    argc=7
    argv[0]=“/args”
    argv[1]=“您好,”
    argv[2]=“世界!”
    argv[3]=“秒”
    argv[4]=“行”
    argv[5]=“第三”
    argv[6]=“行”
    
    因为xargs将输入中由空格分隔的每个标记转换为命令行参数。如果我们告诉xargs使用
    -d SEPARATOR
    选项将每个输入行转换为单独的参数,并使用换行符作为分隔符:

    printf'你好,世界\n第二行\n第三行\n'| xargs-d'\n'./args
    
    我们得到

    argc=4
    argv[0]=“/args”
    argv[1]=“你好,世界!”
    argv[2]=“第二行”
    argv[3]=“第三行”
    
    如果我们告诉xargs,通过添加
    -n2
    选项,每个执行的命令最多添加两个参数

    printf'你好,世界\n第二行\n第三行\n'| xargs-d'\n'-n2./args
    
    我们会找到的

    argc=3
    argv[0]=“/args”
    argv[1]=“你好,世界!”
    argv[2]=“第二行”
    argc=2
    argv[0]=“/args”
    argv[1]=“第三行”
    
    这个输出意味着我们的
    /args
    实际执行了两次。首先是
    /args“你好,世界!”第二行“
    ,第二行是
    /args“第三行”

    xargs的另一个重要选项是
    -r
    ,它告诉xargs在没有任何附加参数的情况下不要运行命令:

    true | xargs-r./args
    
    不输出任何内容,因为xargs看不到任何输入,
    -r
    选项告诉它,如果没有其他参数,就不要运行args程序

    在操作文件名或路径时,
    -0
    (虚线零)选项告诉xargs输入分隔符是nul字符,
    \0
    ,它在C中分隔字符串。如果我们在xargs的输入中使用它,即使是带换行符的字符串也会被正确地分割成参数。例如:

    printf“一件事\n两行\0第二件事”| xargs-0./args
    
    将输出

    argc=3
    argv[0]=“/args”
    argv[1]=“一件事
    “两行”
    argv[2]=“第二件事”
    
    如果以健壮的方式处理文件名或路径,这正是我们想要的


    有没有一种方法不需要xargs就可以做到这一点,并且可以在c文件中完成

    当然:只需阅读标准输入。几乎可以肯定,在所有Unixy系统上,xargs本身都是用C编写的

    [xargs]如何将该格式的字符串分离出来并决定将什么放入数组

    简而言之,这取决于所使用的选项,因为xargs是一个非常强大的小工具

    完整的答案是,看看来源。这个