使用管道通过C中的argv发送和接收字符数组 [英] Sending and receiving character array using piping through argv in C

查看:90
本文介绍了使用管道通过C中的argv发送和接收字符数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在尝试创建一个管道,该管道通过通过argv []连接的管道来回发送char数组.现在,我被困在interface.c中接收数组(从父级到子级发送到c_param的参数)到在db.c处接收字符3和5的过程中.我知道3和5是管道所用argv []的索引,但是我不确定如何接受它并在db.c中打印出我的消息.

So, I'm trying to create a pipe that sends char arrays back and forth through pipes that connect through argv[]. Right now, I'm stuck at receiving the array (param which is sent to c_param from the parent to the child.) in interface.c to receiving the characters 3 and 5 at db.c. I know that 3 and 5 are the index for argv[] that my pipes are at, but I'm not sure how to take that and print out my message in db.c.

interface.c创建管道,将其派生到父进程和子进程中. char数组参数被传输到char数组c_param的子进程中.使用snprintf,我将管道变成了char,以便通过execl和char数组c_param进行发送.

interface.c creates the pipes, forks into a parent process and a child process. The char array param is transfered to the child process to char array c_param. Using snprintf, I made my pipe into a char to send using execl with my char array c_param.

interface.c:

interface.c:

int main (int argc, char *argv[])
{
  int to_Child[2];
  int to_Parent[2];
  int id, toChildPipe, toParentPipe, err;
  char param[100] = "This is the parameter!";
  char sendPipe[100];
  char recPipe[100];

  /*CREATING PIPE*/
  toChildPipe = pipe(to_Child);
  toParentPipe = pipe(to_Parent);


  if(toChildPipe == -1 || toParentPipe == -1)
  {
    printf ("Error on pipe creation: %d", errno);
    exit (1);
  }

  /*Creating Child Process*/
  id = fork();
  if(id == 0)
  {
    /**
     *
     * IN THE CHILD Process
     *
     */
    close(to_Child[1]); //reading
    close(to_Parent[0]); //writing
    char c_param[100];


    toChildPipe = read(to_Child[0], c_param, 100);
    if (toChildPipe == -1)
    {
      //If failed
      printf("Error on read from pipe from parent: %d\n",errno);
      //exit with error
      exit(2);
    }//Error pipe from parent


    snprintf(sendPipe,sizeof(sendPipe), "%d",to_Parent[0]);
    snprintf(recPipe,sizeof(recPipe), "%d",to_Child[0]);

    err = execl("./db","db",sendPipe,recPipe,(char *)0);
      if(err == -1)
      {
        printf("Error on execl: %d\n", errno);
      }//Error execl

      toChildPipe = read(to_Child[0], c_param, 100);
      if (toChildPipe == -1)
      {
        //If failed
        printf("Error on read from pipe from parent: %d\n",errno);
        //exit with error
        exit(2);
      }//Error pipe from parent

    }//CHILD PROCESS

  else if (id > 0)
  {
    /**
     *
     *IN THE PARENT PROCESS
     *
     */
    close(to_Child[0]); //writing
    close(to_Parent[1]); //reading


    toChildPipe = write(to_Child[1],param,100);
    if(toChildPipe == -1)
    {
      printf("Error on write to pipe: %d", errno);
      exit(3);
    }
    /*Piping was successful!*/
    exit(0);
  }//PARENT PROCESS
  else
  {
    exit(4);
  }
}

db.c从interface.c execl启动,并且应该通过argv []接收参数,然后应该将其打印出来. db.c

db.c started up from interface.c execl and should receive the parameters over argv[], which then should print it out. db.c

#include        <errno.h>
#include        <stdio.h>
#include        <stdlib.h>
#include        <string.h>
#include        <sys/types.h>
#include        <unistd.h>


int main(int argc, char *argv[])
{
  FILE *finput;
  int j = 0;
  int fd;
  int toChildPipe;
  char c_param[100];

  if(argc > 1)
  {
    for(j ; j < argc ; j++)
    printf("argv = %s\n", argv[j]);
    printf("argc = %d\n",argc);
  }
  fd = atoi(argv[1]);
  printf("Statement: %s\n", argv[fd]);

  strcpy(c_param, argv[3]);
  printf("filename: %s\n", c_param);

}

这是我得到的当前输出,我知道5和3是发送消息和接收消息的索引,我正在尝试在db.c中打印该消息

This is the current output I'm getting, I'm aware that 5 and 3 are the indexes I need to send a message and receive the message that I'm currently trying to print in db.c

输出(db.c):

argv = db
argv = 5
argv = 3
argc = 3
Statement: TERM=xterm

希望我能给您足够的信息,感谢您愿意给我的任何帮助.预先谢谢你!

I hope I gave you enough information, I appreciate any help you are willing to give me. Thank you in advance!

推荐答案

有很多小错误.您最大的问题是您在db.c中对由interface.c传递给它的参数的假设/断言—在传递的内容和期望的内容之间存在完全不匹配的情况. interface.c中还有很多无关的代码.特别是,孩子在执行db之前从管道读取了数据,因此管道上没有任何内容可供db读取.

There were lots of little things wrong. Your biggest problems were your assumptions/assertions in db.c about the parameters passed to it by interface.c — there was a total mismatch between what was passed and what was expected. There was also a good deal of extraneous code in interface.c. In particular, the child read from the pipe before executing db, so there was nothing left on the pipe for db to read.

这是固定"代码,还有一些调试代码.

Here's the 'fixed' code, with some debug code still in place.

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

int main(void)
{
    int to_Child[2];
    int to_Parent[2];
    int id;
    char param[100] = "This is the parameter!";
    char sendPipe[100];
    char recPipe[100];

    if (pipe(to_Child) == -1 || pipe(to_Parent) == -1)
    {
        printf("Error on pipe creation: %d", errno);
        exit(1);
    }
    printf("Pipes: C(%d,%d), P(%d,%d)\n", to_Child[0], to_Child[1], to_Parent[0], to_Parent[1]);

    id = fork();
    if (id == 0)
    {
        close(to_Child[1]);     // Child does not write to itself
        close(to_Parent[0]);    // Child does not read what it writes
        snprintf(sendPipe, sizeof(sendPipe), "%d", to_Parent[1]);
        snprintf(recPipe, sizeof(recPipe), "%d", to_Child[0]);
        execl("./db", "db", sendPipe, recPipe, (char *)0);
        fprintf(stderr, "Error on execl: %d\n", errno);
        exit(2);
    }
    else if (id > 0)
    {
        close(to_Child[0]);     // Parent does not read childs input
        close(to_Parent[1]);    // Parent does not
        int nbytes = write(to_Child[1], param, 100);
        if (nbytes == -1)
        {
            fprintf(stderr, "Error on write to pipe: %d\n", errno);
            exit(3);
        }
        close(to_Child[1]);
        if ((nbytes = read(to_Parent[0], param, 100)) <= 0)
        {
            fprintf(stderr, "Error on read from pipe: %d\n", errno);
            exit(5);
            }
        printf("Data from pipe: [%.*s]\n", nbytes, param);
        exit(0);
    }
    else
    {
        perror("fork failed");
        exit(4);
    }
}

### db.c

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{

    printf("argc = %d\n", argc);
    for (int j = 0; j < argc; j++)
        printf("argv[%d] = %s\n", j, argv[j]);

    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s write-fd read-fd\n", argv[0]);
        return 1;
    }
    int ofd = atoi(argv[1]);
    int ifd = atoi(argv[2]);
    printf("ifd = %d; ofd = %d\n", ifd, ofd);

    char c_param[100];
    int nbytes = read(ifd, c_param, sizeof(c_param));
    if (nbytes <= 0)
    {
        fprintf(stderr, "Error: failed to read any data (%d)\n", errno);
        return 1;
    }
    printf("Child: [%.*s]\n", nbytes, c_param);

    assert(strlen(c_param) + sizeof(" - sent back to parent") <= sizeof(c_param));
    strcat(c_param, " - sent back to parent");

    if (write(ofd, c_param, nbytes) != nbytes)
    {
        fprintf(stderr, "Error: failed to write all the data (%d)\n", errno);
        return 1;
    }

    return 0;
}

样品运行

Pipes: C(3,4), P(5,6)
argc = 3
argv[0] = db
argv[1] = 6
argv[2] = 3
ifd = 3; ofd = 6
Child: [This is the parameter!]
Data from pipe: [This is the parameter! - sent back to parent]

请注意,该代码将错误报告为标准错误(这是针对错误的).它还限制了打印数据的范围,这可以使查找变得更容易 意外的问题.它不假定数据为空填充;它将打印的长度限制为读取的长度,尽管实际上数据的末尾有许多空值.

Note that the code reports errors to standard error (that's what it is for). It also delimits the printed data which can make it easier to spot unexpected problems. It doesn't assume that the data is null padded; it limits the length printed to the length read, though in fact the data has numerous nulls at the end.

这篇关于使用管道通过C中的argv发送和接收字符数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆