我试图在我编写的程序中将整个重定向的stdin
读入std::string
,并发现在OS X上,seekg和tellg不能正常工作我预计应用于cin
。
这是我的最小例子:
#include <iostream>
using namespace std;
int main()
{
cin.clear();
cin.seekg(0, ios::end);
if (cin.fail() || cin.bad())
cout << "Cin seek failed." << endl;
cout << cin.tellg() << endl;
return 0;
}
在Linux上,当我将这个程序应用到它自己的源代码时,我得到:
alex@linux:~$ g++ size.cpp -o size
alex@linux:~$ ./size < ./size.cpp
225
alex@linux:~$ wc -c size.cpp
225 size.cpp
然而,在OS X上,我得到:
alex@osx:~$ g++ size.cpp -o size
alex@osx:~$ ./size < ./size.cpp
-1
alex@osx:~$ wc -c size.cpp
225 size.cpp
请注意,&#34; Cin寻求失败。&#34;错误消息未打印。为什么是这样?我做错了吗?
更新
这似乎是OS X标准库的一个问题,尽管这适用于Linux上的clang。它适用于使用Homebrew G ++ 4.9的OS X.
alex@osx:~$ g++-4.9 original.cpp -o original
alex@osx:~$ ./original < big.txt
254167055
alex@osx:~$ g++ original.cpp -o original
alex@osx:~$ ./original < big.txt
-1
修改
这里有一些用于将文件读入缓冲区的快速代码
#include <iostream>
#include <stdio.h>
using namespace std;
int main(void)
{
fseek(stdin, 0, SEEK_END);
int read_size = ftell(stdin);
char *buf = new char[read_size];
rewind(stdin);
read_size = fread(buf, 1, read_size, stdin);
string str;
str.append(buf, read_size); // I want to dodge this copy
// because speed is important
delete [] buf;
cout << str.length() << endl;
}
这里有一些慢速代码,用于将文件读入缓冲区
#include <iostream>
using namespace std;
int main(void)
{
string str((std::istreambuf_iterator<char>(cin)),
std::istreambuf_iterator<char>());
cout << str.length() << endl;
}
控制台输出(big.txt是250MB左右):
alex@osx:~$ time ./size < big.txt
254167055
real 0m0.339s
user 0m0.074s
sys 0m0.264s
alex@osx:~$ time ./size-slow < big.txt
254167055
real 1m18.180s
user 1m16.212s
sys 0m0.653s