如何从C中的只读FIFO读取一行?
我在读取只读FIFO中的几行代码时遇到问题。特别是,我必须读两行-一个数字如何从C中的只读FIFO读取一行?,c,fifo,C,Fifo,我在读取只读FIFO中的几行代码时遇到问题。特别是,我必须读两行-一个数字n,后面是一个\n和一个字符串str-我的C程序应该在一个只写FIFO中写入str次。这是我的尝试 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <ctype.h> #include <sys/types.h> #in
n
,后面是一个\n
和一个字符串str
-我的C程序应该在一个只写FIFO中写入str
次。这是我的尝试
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
char *readline(int fd);
int main(int argc, char** argv) {
int in = open(argv[1], O_RDONLY);
mkfifo(argv[2], 0666);
int out = open(argv[2] ,O_WRONLY);
char *line = (char *) malloc(50);
int n;
while (1) {
sscanf(readline(in), "%d", &n);
strcpy(line, readline(in));
int i;
for (i = 0; i < n; i++) {
write(out, line, strlen(line));
write(out, "\n", 1);
}
}
close(in);
close(out);
return 0;
}
char *readline(int fd) {
char *c = (char *) malloc(1);
char line[50];
while (read(fd, c, 1) != 0) {
if (strcmp(c, "\n") == 0) {
break;
}
strcat(line, c);
}
return line;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
字符*读线(int-fd);
int main(int argc,字符**argv){
int in=打开(argv[1],仅限Ordu);
mkfifo(argv[2],0666);
int out=打开(argv[2],仅限O_wr);
字符*行=(字符*)malloc(50);
int n;
而(1){
sscanf(读线(in),%d,&n);
strcpy(行、读行(in));
int i;
对于(i=0;i
代码工作正常,但它在最后一个字符串重复之后放置了随机数目的换行符。此外,该数字在每次执行时都会发生变化
有人能给我一些帮助吗?我没有试着运行你的代码,但是在你的
readline
函数中,你没有用null('\0'
)字符终止行。一旦你点击了“\n”
字符,你只需在循环时中断,并返回字符串行
。在从函数读取行返回之前,请尝试添加'\0'
字符
点击查看更多信息。除了按字符读取和使用“字符串”比较法比较两个字符的效率都很低之外,readline()
还返回一个指向内存的指针,该内存声明为readline()
,即line[50]
只要readline()
返回,内存就会被释放,因此随后访问它会调用取消定义行为
解决此问题的一种可能性是声明缓冲区,以便将该行读入外部readline()
,并向下传递对该行的引用,如下所示:
char * readline(int fd, char * line, size_t size)
{
if ((NULL != line) && (0 < size))
{
char c = 0;
size_t i = 0;
while (read(fd, &c, 1) >0)
{
if ('\n' == c) or (size < i) {
break;
}
line[i] = c;
++i;
}
line [i] = 0;
}
return line;
}
你的代码在我的机器上不起作用,我想说你很幸运能得到任何有意义的结果
以下是一些需要考虑的问题:
readline
返回一个本地定义的静态字符缓冲区(line
),当函数结束时,该缓冲区将被销毁,它所占用的内存将被其他操作自由覆盖
- 如果分配时未将
line
设置为空字节,strcat
将其垃圾值视为字符,并可能尝试在其结束后写入
- 我猜想,您分配了一个1字节的缓冲区(
c
),只是因为您在read
中需要一个char*。这是不必要的(参见下面的代码)。更糟糕的是,在readline
退出之前,您没有释放它,因此它会泄漏内存
while(1)
循环将重新读取文件并将其重新打印到输出fifo,直到时间结束
- 您正在使用一些“重炮”——即strcat
和内存分配——其中有更简单的方法
最后,一些C标准版本可能要求在使用变量之前声明所有变量。看
下面是我如何修改你的代码。请注意,如果第二行长度超过50个字符,则此代码也可能无法正常运行。关于缓冲区限制有一些技巧,但在本例中我不使用任何技巧:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
char *readline(int fd, char * buffer);
int main(int argc, char** argv) {
int in = open(argv[1], O_RDONLY);
int out;
int n;
int i;
char line[50];
memset(line, 0, 50);
mkfifo(argv[2], 0666);
out = open(argv[2] ,O_WRONLY);
sscanf(readline(in, line), "%d", &n);
strcpy(line, readline(in, line));
for (i = 0; i < n; i++) {
write(out, line, strlen(line));
write(out, "\n", 1);
}
close(in);
close(out);
return 0;
}
char *readline(int fd, char * buffer) {
char c;
int counter = 0;
while (read(fd, &c, 1) != 0) {
if (c == '\n') {
break;
}
buffer[counter++] = c;
}
return buffer;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
字符*读线(int-fd,字符*缓冲区);
int main(int argc,字符**argv){
int in=打开(argv[1],仅限Ordu);
指出;
int n;
int i;
字符行[50];
memset(第0、50行);
mkfifo(argv[2],0666);
out=打开(argv[2],仅限O_wr);
sscanf(读线(in,line),%d,&n);
strcpy(行,readline(in,line));
对于(i=0;i
正如你所描述的,这在我的盒子上起作用。使用GCC 4.8.2编译。char*c=(char*)malloc(1)代码>一个1字符缓冲区将没有足够的位置容纳一个字符和一个空终止符;strcat(行,c)
希望它的参数都以nul结尾。并且不要强制转换malloc。谢谢,这对我来说也很好。我只想问最后一个问题:在使用mkfifo
创建之前,如何打开只写FIFO?你说的“之前”是什么意思?你想做什么?好吧,我假设out
FIFO在使用mkfifo(argv[2],0666)
创建后不存在,所以我想知道如何更早地打开它(即open
调用首先出现)。抱歉,这对你来说可能是一个愚蠢的问题,但我对FIFO还很陌生,我必须花很大的努力去理解它们。哦,我在创建命名管道之前尝试访问它时出错了。它工作的唯一原因是上一次运行编辑后留下的命名管道。这就是你要问的,对吗?
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
char *readline(int fd, char * buffer);
int main(int argc, char** argv) {
int in = open(argv[1], O_RDONLY);
int out;
int n;
int i;
char line[50];
memset(line, 0, 50);
mkfifo(argv[2], 0666);
out = open(argv[2] ,O_WRONLY);
sscanf(readline(in, line), "%d", &n);
strcpy(line, readline(in, line));
for (i = 0; i < n; i++) {
write(out, line, strlen(line));
write(out, "\n", 1);
}
close(in);
close(out);
return 0;
}
char *readline(int fd, char * buffer) {
char c;
int counter = 0;
while (read(fd, &c, 1) != 0) {
if (c == '\n') {
break;
}
buffer[counter++] = c;
}
return buffer;
}