C Ostream Dev Null

1// Helpers for ostream inserters -*- C++ -*-
2
3// Copyright (C) 2007-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/ostream_insert.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{ostream}
28 */
29
30#ifndef_OSTREAM_INSERT_H
31#define _OSTREAM_INSERT_H 1
32
33#pragma GCC system_header
34
35#include <iosfwd>
36#include <bits/cxxabi_forced.h>
37
38namespacestd_GLIBCXX_VISIBILITY(default)
39{
40_GLIBCXX_BEGIN_NAMESPACE_VERSION
41
42template<typename _CharT, typename _Traits>
43inlinevoid
44__ostream_write(basic_ostream<_CharT, _Traits>& __out,
45const _CharT* __s, streamsize__n)
46 {
47typedefbasic_ostream<_CharT, _Traits> __ostream_type;
48typedeftypename'>__ostream_type::ios_base __ios_base;
49
50conststreamsize__put = __out.rdbuf()->sputn(__s, __n);
51if (__put != __n)
52__out.setstate(__ios_base::badbit);
53 }
54
55template<typename _CharT, typename _Traits>
56inlinevoid
57__ostream_fill(basic_ostream<_CharT, _Traits>& __out, streamsize__n)
58 {
59typedefbasic_ostream<_CharT, _Traits> __ostream_type;
60typedeftypename'>__ostream_type::ios_base __ios_base;
61
62const _CharT __c = __out.fill();
63for (; __n > 0; --__n)
64 {
65consttypename _Traits::int_type __put = __out.rdbuf()->sputc(__c);
66if (_Traits::eq_int_type(__put, _Traits::eof()))
67 {
68__out.setstate(__ios_base::badbit);
69break;
70 }
71 }
72 }
73
74template<typename _CharT, typename _Traits>
75basic_ostream<_CharT, _Traits>&
76__ostream_insert(basic_ostream<_CharT, _Traits>& __out,
77const _CharT* __s, streamsize__n)
78 {
79typedefbasic_ostream<_CharT, _Traits> __ostream_type;
80typedeftypename'>__ostream_type::ios_base __ios_base;
81
82typename'>__ostream_type::sentry __cerb(__out);
83if (__cerb)
84 {
85__try
86 {
87conststreamsize__w = __out.width();
88if (__w > __n)
89 {
90constbool__left = ((__out.flags()
91 & __ios_base::adjustfield)
92 __ios_base::left);
93if (!__left)
94 __ostream_fill(__out, __w - __n);
95if (__out.good())
96 __ostream_write(__out, __s, __n);
97if (__left && __out.good())
98 __ostream_fill(__out, __w - __n);
99 }
100else
101 __ostream_write(__out, __s, __n);
102__out.width(0);
103 }
104__catch(__cxxabiv1::__forced_unwind&)
105 {
106__out._M_setstate(__ios_base::badbit);
107__throw_exception_again;
108 }
109__catch(...)
110 { __out._M_setstate(__ios_base::badbit); }
111 }
112return__out;
113 }
114
115// Inhibit implicit instantiations for required instantiations,
116 // which are defined via explicit instantiations elsewhere.
117#if_GLIBCXX_EXTERN_TEMPLATE
118externtemplate ostream& __ostream_insert(ostream&, constchar*, streamsize);
119
120#ifdef_GLIBCXX_USE_WCHAR_T
121externtemplate wostream& __ostream_insert(wostream&, constwchar_t*,
122 streamsize);
123#endif
124#endif
125
126_GLIBCXX_END_NAMESPACE_VERSION
127} // namespace std
128
129#endif /* _OSTREAM_INSERT_H */
130

Question

I would like to be able to do:

The /dev/null device is a special file, not a directory, so one cannot move a whole file or directory into it with the Unix mv command. References in computer culture. Sudo rm /dev/null sudo mknod -m 0666 /dev/null c 1 3 You should reconstruct it because a lot of scripts by default send output to /dev/null. C opens the istream object cin when the program starts. Similarly, ostream is the basis for output. The prototypes above are for inserters and extractors for pointers to null terminated character. Dovecot mail server. Contribute to dovecot/core development by creating an account on GitHub.

C Ostream Dev Null Function

EDIT: single line solution is crucial since this is for logging purposes. These will be all around the code.

inside foo will print the string to screen or something of the sort.

now since stringstream's operator<< returns ostream&, foo's signature must be:

but how can I convert ostream& to string? (or char*).Different approaches to achieving this use case are welcome as well.

Solution

The obvious solution is to use dynamic_cast in foo. But the givencode still won't work. (Your example will compile, but it won't do whatyou think it should.) The expression std::ostringstream() is a temporary, you can't initialize a non-const reference with a temporary,and the first argument of std::operator<<( std::ostream&, char const*)is a non-const reference. (You can call a member function on atemporary. Like std::ostream::operator<<( void const* ). So the codewill compile, but it won't do what you expect.

You can work around this problem, using something like:

std::ostream::flush() returns a non-const reference, so there are nofurther problems. And on a freshly created stream, it is a no-op.Still, I think you'll agree that it isn't the most elegant or intuitivesolution.

C Ostream Dev Null

What I usually do in such cases is create a wrapper class, whichcontains it's own std::ostringstream, and provides a templatedmemberoperator<< which forwards to the containedstd::ostringstream. Your function foo would take a constreference to this—or what I offen do is have the destructor callfoo directly, so that the client code doesn't even have to worry aboutit; it does something like:

The function log() returns an instance of the wrapper class (but seebelow), and the (final) destructor of this class calls your functionfoo.

There is one slight problem with this. The return value may be copied,and destructed immediately after the copy. Which will wreck havoc withwhat I just explained; in fact, since std::ostringstream isn'tcopyable, it won't even compile. The solution here is to put all of theactual logic, including the instance of std::ostringstream and thedestructor logic calling foo in a separate implementation class, havethe public wrapper have a boost::shared_ptr to it, and forward. Orjust reimplement a bit of the shared pointer logic in your class:

Note that it's easy to extend this to support optional logging; justprovide a constructor for the LogWrapper which sets collector toNULL, and test for this in the operator<<.

EDITED:

One other thing occurs to me: you'll probably want to check whether thedestructor is being called as a result of an exception, and not callfoo in that case. Logically, I'd hope that the only exception youmight get is std::bad_alloc, but there will always be a user whowrites something like:

where the + is a user defined overload which throws.

OTHER TIPS

I would suggest you to use this utility struct:

And use it as:

Demo (with few more example) : http://ideone.com/J995r

More on my blog : Create string on the fly just in one line

C Ostream Dev Null Function

You could use a proxy object for this; this is a bit of framework, but if you want to use this notation in a lot of places then it may be worth it:

This program prints

The idea is to have a little wrapper class which can be implicitely converted into a std::string. The << operator is simply forwarded to the contained std::stringstream. The make_stream() function is strictly speaking not necessary (you could also say StreamProxy(), but I thought it looks a bit nicer.

A couple of options other than the nice proxy solution just presented by Frerich Raabe:

  • Define a static string stream variable in the header that defines the logging function and use the comma operator in your invocation of the logging function so that this variable is passed rather than the ostream& returned by the stream insertion operator. You can use a logging macro to hide this ugliness. The problem with this solution is that it is a bit on the ugly side, but this is a commonly used approach to logging.

  • Don't use C++ I/O. Use a varargs C-style solution instead. Pass a format string as the first argument, with the remaining arguments being targets for that format string. A problem with this solution is that even if your compiler is smart enough to ensure that printf and its cousins are safe, the compiler probably won't know that this new function is a part of the printf family. Nonetheless, this is also a commonly used approach.

Dev Null 2-1

If you don't mind using macros functions, you can make the logging function accept const string&, and use the following macro

And suppose you foo has signature void foo(const string&), you only need the one-liner

This was inspired by James Kanze's answer about static_cast and stringstream.flush. Without the .flush() the above method fails with unexpected output.

Please note that this method should not leak memory, as temporary values, whether in the pointer form or not, are still allocated on the stack and hence destroyed upon return.

Since you're converting to string anyways, why not

This is not possible. As the name ostream implies, it is used for output, for writing to it. You could change the parameter to stringstream&. This class has the method str() which returns a std::string for your use.

EDIT I did not read the issue with operator << returning ostream&. So I guess you cannot simply write your statements within the functions argument list but have to write it before.

You can create a small wrapper around std::ostringstream that will convert back to std::string on use, and have the function take a std::string const &. The first approach to this solution can be found in this answer to a different question.

C ostream dev null

On top of that, you can add support for manipulators (std::hex) if needed.

Not affiliated with StackOverflow

Get answers to millions of questions and give back by sharing your knowledge with others.

Sign up for an account.