标签: istream

非复制istringstream

因此istringstream,在初始化时复制字符串的内容,例如

string moo("one two three four");
istringstream iss(moo.c_str());
Run Code Online (Sandbox Code Playgroud)

我想知道是否有办法std::istringstream使用给定c_str的缓冲区而不复制东西.这样,在传递std::istringstream&istream&作为参数的函数之前,它不必复制大量内存.

我一直在努力做的是转换一些只接受std::ifstream&参数的函数(它们主要是解析器)istream&.我是否必须为此创建自己的istream子类?

c++ istream istringstream

11
推荐指数
2
解决办法
2869
查看次数

区分读循环中的失败和文件结束

从istream中读取的惯用循环是

while (thestream >> value)
{
  // do something with value
}
Run Code Online (Sandbox Code Playgroud)

现在这个循环有一个问题:它不会区分循环是由于文件结束还是由于错误而终止.例如,采取以下测试程序:

#include <iostream>
#include <sstream>

void readbools(std::istream& is)
{
  bool b;
  while (is >> b)
  {
    std::cout << (b ? "T" : "F");
  }
  std::cout << " - " << is.good() << is.eof() << is.fail() << is.bad() << "\n";
}

void testread(std::string s)
{
  std::istringstream is(s);
  is >> std::boolalpha;
  readbools(is);
}

int main()
{
  testread("true false");
  testread("true false tr");
}
Run Code Online (Sandbox Code Playgroud)

第一次调用testread包含两个有效的bool,因此不是错误.第二个呼叫以第三个不完整的bool结束,因此是一个错误.然而,两者的行为是相同的.在第一种情况下,读取布尔值失败,因为没有,而在第二种情况下,它失败,因为它是不完整的,并且在两种情况下都会命中EOF.实际上,上面的程序输出两次相同的行:

TF - 0110
TF - …
Run Code Online (Sandbox Code Playgroud)

c++ error-handling istream

11
推荐指数
1
解决办法
1746
查看次数

如何在C++中从istream对象读取时检测空行?

如何检测线是否为空?

我有:

1
2
3
4

5
Run Code Online (Sandbox Code Playgroud)

我正在用istream r读这个:

int n;
r >> n
Run Code Online (Sandbox Code Playgroud)

我想知道当我到达4到5之间的空间时.我尝试读取为char并使用.peek()来检测\n但是这会检测到数字1之后的\n.以上输入的翻译是:1 \n2 \n3 \n4 \n \n5 \n如果我是正确的...

因为我要操作整数,所以我宁愿把它们作为整数读取而不是使用getline然后转换为int ...

c++ string input stream istream

11
推荐指数
2
解决办法
6万
查看次数

不应该istream :: peek()总是返回你刚刚putback()?

直观地说,从C++规范来看,它看起来好像istream::putback( c )应该总是安排输入缓冲区,以便下一次调用istream::peek()应该读取字符c.这不正确吗?我问,因为随Xcode 4.6发布的最新版本的libc ++似乎并未在所有情况下强制执行此行为 - 特别是当最后一个字符位于EOF时.如果您使用unget()而不是,也是如此putback( c ).

libc ++的行为是正确的,还是我对如何putback()/unget()正确行事的直觉?

考虑这个示例代码,它与libstdc ++一起使用但不与libc ++一起使用(断言失败).

#include <sstream>
#include <cassert>

int main(int argc, const char * argv[])
{
    std::istringstream in( "[Test]" );

    while( in )
    {
        int c = in.get();
        if( c == ']' )
        {
            in.putback( c );
            assert( in.peek() == c );   // Fails with libc++. Succeeds with libstdc++.
            break;
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ istream libc++

11
推荐指数
1
解决办法
504
查看次数

在C++中,当cin是bash heredoc时调用fork会导致重复的输入片段

我正在用C++实现类似shell的程序.它有一个从cin,forks读取并等待孩子的循环.

如果输入是交互式的,或者如果它是从另一个程序传送的,那么这种方法很好.但是,当输入是bash heredoc时,程序会重新读取部分输入(有时是无限期).

我知道子进程继承了父进程的文件描述符,包括共享文件偏移量.但是,这个例子中的孩子没有从cin读取任何东西,所以我认为它不应该触及偏移量.我有点难过为什么会这样.


TEST.CPP:

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char **argv)
{
    std::string line;
    while (std::getline(std::cin, line)) {
        pid_t pid = fork();
        if (pid == 0) { // child
            break; // exit immediately
        }
        else if (pid > 0) { // parent
            waitpid(pid, nullptr, 0);
        }
        else { // error
            perror("fork");
        }

        std::cout << getpid() << ": " << line << "\n";
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我编译如下:

g++ test.cpp -std=c++11
Run Code Online (Sandbox Code Playgroud)

然后我运行它:

./a.out <<EOF …
Run Code Online (Sandbox Code Playgroud)

c++ bash fork heredoc istream

11
推荐指数
1
解决办法
282
查看次数

可以`std :: istream :: operator >>()`接受整数基数前缀,比如stdio的%i格式说明符吗?

当使用的scanf()和它的变体,该格式说明%i将接受作为十六进制数据(加前缀"0x"为),八进制(前缀"0"),或十进制(无前缀),因此,例如字符串"0x10的","020 "和"16"都转换为十进制值为16的整数.

这可以通过std::istream::operator>>格式化输入完成吗?

使用普通的>> i无I/O操纵器"为0x10"被转换成零(或者更确切地说,前导0,则"×10"的部分不被处理),以及"020",以20 hex,octdec操纵行为像%x,%o%d分别.我正在寻找一个像%i.一样的通用整数输入操纵器.

有趣的是,hex操纵器可能同时接受"0x10"和"10"转换为16位小数.

如果您可能想知道,我正在实现一个表达式求值程序,并且我希望使用C/C++前缀约定允许整数操作数为十六进制,八进制或十进制.当前使用的实现sscanf()会自动使用%i,我很好奇是否可以修改它以使用iostream而无需显式解析数字格式.

c++ scanf istream iomanip

10
推荐指数
1
解决办法
1120
查看次数

如何使用带字符串的istream

我想把一个文件读成一个字符串.我正在寻找有效的方法.

使用固定大小的*char缓冲区

我收到了Tony 的回答是什么创建了一个16kb的缓冲区并读入该缓冲区并附加缓冲区,直到没有其他内容可读.我理解它是如何工作的,我发现它非常快.我不明白的是,在答案的评论中,据说这种方式将所有内容复制两次.但据我所知,它只发生在内存中,而不是发生在磁盘上,所以它几乎是不可察觉的.它是从缓冲区复制到内存中的字符串的问题吗?

使用istreambuf_iterator

我收到的另一个答案是使用istreambuf_iterator.代码看起来美观而且极小,但速度极慢.我不知道为什么会这样.为什么那些迭代器这么慢?

使用memcpy()

对于这个问题,我收到的评论是我应该使用memcpy(),因为它是最快的本机方法.但是如何将memcpy()与字符串和ifstream对象一起使用?是不是ifstream应该使用自己的读取功能?为什么使用memcpy()破坏可移植性?我正在寻找与VS2010以及GCC兼容的解决方案.为什么memcpy()不适用于那些?

+还有其他任何有效的方法吗?

对于小的<10 MB二进制文件,你推荐什么,我使用什么shell?

(我不想将这个问题分成几部分,因为我对如何将ifstream读入字符串的不同方式之间的比较更感兴趣)

c++ string gcc istream visual-studio

10
推荐指数
1
解决办法
1万
查看次数

如何找出std :: istream中可用的字节数?

如果我想要一个缓冲区read()的内容std::istream,我将不得不首先了解有多少数据可用来知道缓冲区的大小.为了从istream中获取可用字节数,我目前正在做这样的事情:

std::streamsize available( std::istream &is )
{
    std::streampos pos = is.tellg();
    is.seekg( 0, std::ios::end );
    std::streamsize len = is.tellg() - pos;
    is.seekg( pos );
    return len;
}
Run Code Online (Sandbox Code Playgroud)

同样地,由于std :: istream :: eof()不是一个非常有用的基金AFAICT,为了找出是否istream得到指针在流的末尾,我这样做:

bool at_eof( std::istream &is )
{
    return available( is ) == 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

有没有更好的方法来获取可用字节数istream?如果不是在标准库中,也许在boost中?

c++ boost stl istream

9
推荐指数
1
解决办法
5207
查看次数

C#IStream实现了IStream

首先,这与此没有重复是否已存在COM互操作IStream的包装类?因为我需要在另一个方向实施.我需要创建一个从IO.Stream到IStream的IStream实现.但在我开始尝试这样做之前,想问一下是否有人知道已经存在的实施或任何关于此的文章.我在.net框架中找不到任何东西,谷歌只给了我从IStream到IO.Stream的实现结果.那么有人对我有一个很好的建议吗?我真的不知道如何开始,因为第一个成员(克隆 - >创建一个新的流对象,它引用与原始流相同的字节,但提供一个单独的搜索指针指向这些字节)让我很麻烦.我不知道如何基于IO.Stream做到这一点.

c# stream wrapper istream

9
推荐指数
1
解决办法
2171
查看次数

如何使用IOStream存储格式设置?

为用户定义的类型创建格式化输出时,通常需要定义自定义格式标记.例如,如果自定义字符串类可以选择在字符串周围添加引号,那将是很好的:

String str("example");
std::cout << str << ' ' << squotes << str << << ' ' << dquotes << str << '\n';
Run Code Online (Sandbox Code Playgroud)

应该产生

example 'example' "example"
Run Code Online (Sandbox Code Playgroud)

很容易创建操纵器来更改格式化标志本身:

std::ostream& squotes(std::ostream& out) {
    // what magic goes here?
    return out;
}
std::ostream& dquotes(std::ostream& out) {
    // similar magic as above
    return out;
}
std::ostream& operator<< (std::ostream& out, String const& str) {
    char quote = ????;
    return quote? out << quote << str.c_str() << quote: str.c_str();
}
Run Code Online (Sandbox Code Playgroud)

...但是操纵器如何存储哪些引号应该与流一起使用,然后让输出操作符检索值?

c++ iostream istream ostream

9
推荐指数
1
解决办法
356
查看次数