【发布时间】:2013-11-28 17:00:42
【问题描述】:
我有以下问题:
我的工作是编写一个程序,该程序接受通过标准输入传递给它的无符号整数,并仅打印出超过 2 位设置为 1 的数字。我应该如何有效地做到这一点?我做了一个程序版本,我使用 mmap 从文件中读取数字,而且速度非常快。我读它就像一个非常大的 *char 缓冲区并使用 strtol 我“擦掉”每个数字并进行检查等等。
有没有办法以同样的方式对通过标准输入的字符串进行操作?我虽然关于使用 fread 进行缓冲,但是有一个问题,缓冲区会切断数字(这意味着如果我通过“1024 35”并且我有一个 6 字节的缓冲区,我将得到“1024 3”),我不禁想到如何解决这个问题。
来源:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h> /* mmap() is defined in this header */
#include <fcntl.h>
#include<string.h>
#include"apue.h"
int main (int argc, char *argv[])
{
int fdin, fdout;
char *src, *dst;
struct stat statbuf;
/* open the input file */
if ((fdin = open (argv[1], O_RDONLY)) < 0)
{printf("can't open %s for reading", argv[1]);return 1;}
/* find size of input file */
if (fstat (fdin,&statbuf) < 0)
{printf("fstat error");return 1;}
/* mmap the input file */
if ((src = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0))
== (caddr_t) -1)
{printf("mmap error for input");return 1;}
char* beg=src;
long x;
char* end=&src[statbuf.st_size-1];
while(src<end)
{
beg=src;
x = strtol (src,&src,10);
if(!((x != 0) && ((x & (~x + 1)) == x)))
fwrite(beg, 1, (int)(src-beg), stdout);
}
return 0;
}
【问题讨论】:
-
这些数字是作为文本传递的,还是直接以
unsigned int形式写入流中? -
为什么选择mmap?除非您有某种方法可以检测到数字何时中断。一个在你停止阅读标准输入的地方自然结束的数字,你仍然在同一条船上。例如如果您传递
1 2 3并且标准输入中的任何内容都在两者之后结束。你怎么知道 2 已经完成,实际上不应该是1 23456 3? -
它们作为文本传递。
-
那么您可能会花费更多时间将文本转换为数字,而不是使用
mmap获得的时间。保持简单。 -
意思是我应该如何解决这个问题?我正确的思维方式是完全错误的吗?有没有办法像使用 mmap 操作文件一样舒适地从标准输入读取字符串?