我是C.的管道新手。 我正在努力写下#34;你好"来自儿童过程的管道&从父进程读取相同的内容,但是我得到了意外的输出。
我使用这段代码:
#include<stdio.h>
#include<unistd.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
pid_t pid;
int fds[2];
int ret;
char ch[20];
ret = pipe(fds);
if(ret == -1)
{
perror("pipe failed");
exit(0);
}
pid = fork();
if (pid == 0)
{
printf("Child process\n");
write(fds[1],"Hello",5);
}
if (pid > 0)
{
printf("Parent Process\n");
read(fds[0],ch,15);
printf("%s\n",ch);
}
return 0;
}
我将此作为输出:
Parent Process
Child process
Helloq.
我无法理解为什么这个额外的&#34; q。&#34;来了吗?
答案 0 :(得分:2)
您正在尝试写入6个字节,但是将大小设置为5.您还需要在Hello结束时发送'\0'
。
只需将您的写入通话更改为
write(fds[1],"Hello",6);
你应该没事。
答案 1 :(得分:0)
在将数据写入缓冲区之前,在代码中使用<div class="collapse navbar-collapse js-navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="about-us.html">About Us</a></li>
<li class="dropdown mega-dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Products<span class="icon ion-ios-arrow-down pull-right"></span></a>
<ul class="dropdown-menu mega-dropdown-menu row navigation">
<div class="container">
<li>
<div class="col-sm-4">
<div class="left-area">
<button type="button" class="btn all-product-btn">All Products</button>
<hr>
<ul id="nav">
<li class="active-class" data="Employee"><a href="employee-monitoring-system.html">Employee Monitoring System</a></li>
<li data="Hospital"><a href="hospital-management-software/index.html" >Hospital Management Software</a></li>
<li data="School"><a href="school-management-system/index.html">School Management System</a></li>
<li data="Inventory"><a href="inventory-management-software/index.html">Inventory Management Software</a></li>
<li data="Fee"><a href="fee-management-system.html">Fee Management System</a></li>
<li data="Lead"><a href="lead-management-system/index.html">Lead Management System</a></li>
<li data="Customer"><a href="customer-relationship-management.html">Customer Relationship Management</a></li>
<li data="Human"><a href="human-resource-management-software.html">Human Resource Management Software</a></li>
<li data="Enterprises"><a href="enterprises-resource-planning.html">Enterprises Resource Planning</a></li>
<li data="Commerce"><a href="customize-e-commerce-portals.html">Customize E-Commerce Portals</a></li>
</ul>
</div>
</div>
<div id="Employee" class="col-sm-8 nav-hide" >
<div class="right-area">
<h3>Employee Monitoring System</h3>
<p></p>
<div class="col-md-7">
<ul>
<li>A Unique System that peforms employee monitoring.</li>
<li>Prevents unauthorised exchange of data</li>
<li>Could not be identified by a user</li>
<li>Captures their Keystrokes</li>
<li>Caputres their Screen Shots</li>
<li>Uploads text files</li>
</ul>
</div>
<div class="col-md-5"><img src="img/products/ems.jpg" class="img-responsive"></div>
</div>
</div>
</li>
<div id="Hospital" class="col-sm-8 nav-hide" style="display:none">
<div class="right-area">
<h3>Hospital Management Software</h3>
<div class="col-md-7">
<ul>
<li>Reduces the amount of paper work.</li>
<li>Recording information about the Patients that come.</li>
<li>Generating bills.</li>
<li>Recording information related to diagnosis given to Patients.</li>
<li>Keeping record of the Immunization provided to children/patients.</li>
</ul>
</div>
<div class="col-md-5"><img src="img/products/hospital.jpg" class="img-responsive"></div>
</div>
</div>
</ul>
</div>
函数,该缓冲区使用常量字节填充内存。等,
memset()
完整的代码可能会对您有所帮助。
memset(ch,'\0',20);
答案 2 :(得分:0)
由于您没有记录从管道读取的字节数,因此您的代码正在打印ch
变量中已有的垃圾。有很多方法可以解决它。此代码显示其中两个。我使用memset()
来确保ch
包含一些数据(并且赋值确保它以空值终止)。
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
pid_t pid;
int fds[2];
int ret;
char ch[20];
memset(ch, 'X', sizeof(ch)-1);
ch[sizeof(ch)-1] = '\0';
ret = pipe(fds);
if (ret == -1)
{
perror("pipe failed");
exit(0);
}
pid = fork();
if (pid == 0)
{
printf("Child process\n");
write(fds[1], "Hello", 5);
}
else if (pid > 0)
{
printf("Parent Process\n");
int nbytes = read(fds[0], ch, 15);
printf("[%s]\n", ch);
printf("[%.*s]\n", nbytes, ch);
ch[nbytes] = '\0';
printf("[%s]\n", ch);
}
else
fprintf(stderr, "fork() failed\n");
return 0;
}
代码记录了写入的字节数(真正勤奋的代码也能确保写入正确数量的数据)。它打印数据3次 - 一次使用您的原始技术,然后使用从管道读取的字节数限制输出,然后空终止数据,以便它可以写为简单的字符串。
%.*s
转换规范使用两个值 - 数字和字符串。该数字是将要写入的最大字节数。如果字符串比那短,那就这样吧。如果字符串较长,则忽略多余的字节。
示例输出:
Parent Process
[HelloXXXXXXXXXXXXXX]
[Hello]
[Hello]
Child process
这是管道程序输出的结果。在视觉上,在终端上,我通常得到:
Parent Process
Child process
[HelloXXXXXXXXXXXXXX]
[Hello]
[Hello]
两个输出都有效。注意数据的第一次打印如何包括许多X,因为没有从管道读取空字节。
另一种方法是让孩子将以null结尾的字符串的null写入管道:write(fds[1], "Hello", sizeof("Hello"));
。其他选项包括在管道上写入字符串的长度,然后写入数据,然后读取长度和多个字节的数据。这是TLV(类型,长度,值)编码系统的次要变体 - 未明确指定类型,因为它被假定为char
。