I am trying to use a stringstream as a buffer but I am unable to update the underlying streambuf :
#include <iostream>
#include <sstream>
int main () {
std::stringstream ss(std::ios_base::app|std::ios_base::in|std::ios_base::out); //ostringstream gives the same output
ss << "foo";
std::cout << "position get: " << ss.tellg() << std::endl;
std::cout << "position put: " << ss.tellp() << std::endl;
ss << "b";
std::cout << "position get: " << ss.tellg() << std::endl;
std::cout << "position put: " << ss.tellp() << std::endl;
char c;
ss >> c;
std::cout << "position get: " << ss.tellg() << std::endl;
std::cout << "position put: " << ss.tellp() << std::endl;
ss.ignore(1);
std::cout << "position get: " << ss.tellg() << std::endl;
std::cout << "position put: " << ss.tellp() << std::endl;
std::cout << ss.str() << std::endl;
return 0;
}
yields:
position get: 0
position put: 3
position get: 0
position put: 4
position get: 1
position put: 4
position get: 2
position put: 4
foob
Is it possible to force a reallocation of the streambuf underlying object ? If not, is this reallocation automatic and in which circumstance is it triggered ?
I know I can use ss.str to change the underlying buffer. But it is a pain to use it to manually update the buffer to a substr's version.
Note: I am doing a school project and must compile to c++98, hence, if you have a solution which is comptabible, it would be much appreciated.
Related
I have following test example:
#include <iostream>
#include <vector>
void foo (std::vector<int> value) {
std::cout << "value "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
}
void foo2 (std::vector<int>&& rvalure_ref) {
std::cout << "rvalue_ref "
<< &rvalure_ref
<< " "
<< rvalure_ref.data()
<< " "
<< rvalure_ref.size()
<< std::endl;
}
int main() {
std::vector<int> value(5, 0);
std::cout << "init "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
foo(std::move(value));
std::cout << "done "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
}
The result of the code above is:
init 0x7ffed27c6450 0x56480bc1eeb0 5
value 0x7ffed27c6470 0x56480bc1eeb0 5
done 0x7ffed27c6450 0 0
Looks great:
Now, move to:
#include <iostream>
#include <vector>
void foo (std::vector<int> value) {
std::cout << "value "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
}
void foo2 (std::vector<int>&& rvalure_ref) {
std::cout << "rvalue_ref "
<< &rvalure_ref
<< " "
<< rvalure_ref.data()
<< " "
<< rvalure_ref.size()
<< std::endl;
}
int main() {
std::vector<int> value(5, 0);
std::cout << "init "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
foo2(std::move(value));
std::cout << "done "
<< &value
<< " "
<< value.data()
<< " "
<< value.size()
<< std::endl;
}
The result is:
init 0x7ffccc93a5c0 0x56124b3a8eb0 5
rvalue_ref 0x7ffccc93a5c0 0x56124b3a8eb0 5
done 0x7ffccc93a5c0 0x56124b3a8eb0 5
My problem is:
For the 1st case, it is perfectly called by "move semantics", and as you see, the ownership of the vector has been transfered to the function parameter. Finally, at "done", the data is null to verify the the vector at main() no longer owns the vector.
Now to explicitly claim the parameter is "rvalue reference", as case 2. As you see, actually it is like "call by (l)reference".
How can I figure out it?
I was playing around with pointers and got results I did not expect:
#include <iostream>
#include <vector>
int main() {
int arr[4] = { 1, 2, 3, 4 };
int* pArr = arr;
std::cout << "First number: " << *pArr << " at address: " << pArr;
pArr++;
std::cout << "\nSecond number: " << *pArr << " at address: " << pArr;
pArr++;
std::cout << "\nThird number: " << *pArr << " at address: " << pArr;
pArr++;
std::cout << "\nFourth number: " << *pArr << " at address: " << pArr;
int* pArr2 = arr;
std::cout << "\n"
<< *pArr2++ << "\n"
<< *pArr2++ << "\n"
<< *pArr2++ << "\n"
<< *pArr2++ << "\n";
/*
int* pArr2 = arr;
std::cout << "\n"
<< ++ * pArr2 << "\n"
<< * ++pArr2 << "\n";
*/
}
The two different results:
1 2 3 4 - as expected using the first method
4 3 2 1 - using cout with multiple arguments I do not know the proper name.
So my question is - why does this happen? Using multiple cout statements results in expected for me code, while using just 1 cout results in backwards solution.
As a side note, another confusing thing to me is that pre-increment results in all values being equal. In the commented bit of code, the result is 3 3, no matter the ++ placement with respect to the *.
This code:
std::cout << "\n" << *pArr2++ << "\n";
std::cout << "\n" << *pArr2++ << "\n";
has a well defined order of modifications to pArr and will print
1
2
But this code:
std::cout << "\n" << *pArr2++ << "\n" << *pArr2++ << "\n";
invokes undefined behavior before c++17, because there are multiple modifications to pArr2 that are unsequenced. The program has UB, so it could print anything.
From c++17, there is a sequence point between the modifications, and the above code is guaranteed to print:
1
2
So in c++11 the Chrono Library provides, duration_cast:
Computations are done in the widest type available and converted, as if by static_cast, to the result type only when finished
And c++17's floor:
Returns the greatest duration t representable in ToDuration that is less or equal to d
So for all x will the result of these 2 calls be equal:
chrono::duration_cast<chrono::seconds>(x)
chrono::floor<chrono::seconds>(x)
As far as I can tell, same as the difference between static_cast and std::floor: Negatives are rounded down instead of truncated toward zero.
#include <iostream>
#include <chrono>
using namespace std::chrono_literals;
int main() {
std::cout << "duration_cast:" << std::endl;
std::cout << "1.4s: " << std::chrono::duration_cast<std::chrono::seconds>(1400ms).count() << std::endl;
std::cout << "1.5s: " << std::chrono::duration_cast<std::chrono::seconds>(1500ms).count() << std::endl;
std::cout << "1.6s: " << std::chrono::duration_cast<std::chrono::seconds>(1600ms).count() << std::endl;
std::cout << "-1.4s: " << std::chrono::duration_cast<std::chrono::seconds>(-1400ms).count() << std::endl;
std::cout << "-1.5s: " << std::chrono::duration_cast<std::chrono::seconds>(-1500ms).count() << std::endl;
std::cout << "-1.6s: " << std::chrono::duration_cast<std::chrono::seconds>(-1600ms).count() << std::endl;
std::cout << "floor:" << std::endl;
std::cout << "1.4s: " << std::chrono::floor<std::chrono::seconds>(1400ms).count() << std::endl;
std::cout << "1.5s: " << std::chrono::floor<std::chrono::seconds>(1500ms).count() << std::endl;
std::cout << "1.6s: " << std::chrono::floor<std::chrono::seconds>(1600ms).count() << std::endl;
std::cout << "-1.4s: " << std::chrono::floor<std::chrono::seconds>(-1400ms).count() << std::endl;
std::cout << "-1.5s: " << std::chrono::floor<std::chrono::seconds>(-1500ms).count() << std::endl;
std::cout << "-1.6s: " << std::chrono::floor<std::chrono::seconds>(-1600ms).count() << std::endl;
return 0;
}
.
duration_cast:
1.4s: 1
1.5s: 1
1.6s: 1
-1.4s: -1
-1.5s: -1
-1.6s: -1
floor:
1.4s: 1
1.5s: 1
1.6s: 1
-1.4s: -2
-1.5s: -2
-1.6s: -2
https://wandbox.org/permlink/SsmpRz6RkvbL6Sru
I am learning about different stream state flags/functions in C++ such as good(), goodbit, bad(), badbit and so on. While testing with std::cin, I am unable to pass cin as an argument to a function (the compiler shows a lot of errors)
#include <iostream>
#include <sstream>
void print_state (const std::istream& stream) {
std::cout << " good()=" << stream.good();
std::cout << " eof()=" << stream.eof();
std::cout << " fail()=" << stream.fail();
std::cout << " bad()=" << stream.bad();
}
int main() {
std::cin.clear (std::ios::goodbit);
std::cout << "goodbit: " << print_state(std::cin) << std::endl;
std::cin.clear (std::ios::eofbit);
std::cout << "eofbit: " << print_state(std::cin) << std::endl;
std::cin.clear (std::ios::failbit);
std::cout << "failbit: " << print_state(std::cin) << std::endl;
std::cin.clear (std::ios::badbit);
std::cout << "badbit: " << print_state(std::cin) << std::endl;
return 0;
}
Desired output:
goodbit: good()=1 eof()=0 fail()=0 bad()=0
eofbit: good()=0 eof()=1 fail()=0 bad()=0
failbit: good()=0 eof()=0 fail()=1 bad()=0
badbit: good()=0 eof()=0 fail()=1 bad()=1
I know I can call the function directly with cin, such as std::cin.good(), but I want to know how can I pass cin as an argument to a function.
Edit:
I get a LOT of errors during compilation. An example:
F:\cpp_programming\stream_states.cpp: In function 'int main()':
F:\cpp_programming\stream_states.cpp:13:27: error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'void')
std::cout << "goodbit: " << print_state(std::cin) << std::endl;
~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Since print_state does not return a value, it cannot be used with the insertion operator <<. The simplest way to correct this, is to call print_state on its own.
print_state(std::cin);
The corrected code is given below:
#include <iostream>
#include <sstream>
void print_state (const std::istream& stream) {
std::cout << " good()=" << stream.good();
std::cout << " eof()=" << stream.eof();
std::cout << " fail()=" << stream.fail();
std::cout << " bad()=" << stream.bad();
}
int main() {
std::cin.clear (std::ios::goodbit);
std::cout << "goodbit: "; print_state(std::cin); std::cout << std::endl;
std::cin.clear (std::ios::eofbit);
std::cout << "eofbit: "; print_state(std::cin); std::cout << std::endl;
std::cin.clear (std::ios::failbit);
std::cout << "failbit: "; print_state(std::cin); std::cout<< std::endl;
std::cin.clear (std::ios::badbit);
std::cout << "badbit: "; print_state(std::cin); std::cout << std::endl;
return 0;
}
To answer my own question
cin can be passed to a function as a function argument, such as:
functionName(std::cin);
I am working on the latest revision of the C++ programming language (think it's 5) and run into a problem with g++ version 5.2.
My code is a variation of Small_size template from chap 24.
#include <iostream>
template<int N>
bool is_small ()
{
std::cerr << sizeof(N) << std::endl;
std::cerr << N << std::endl;
return N <= 255;
}
bool ism (int i_n)
{
return i_n <= 255;
}
int main ()
{
std::cout << "hallo welt" << std::endl;
std::cout << 0 << " " << is_small<0> << std::endl;
std::cout << 255 << " " <<is_small<255> << std::endl;
std::cout << -4100000000 << " " << is_small<-4100000000> << std::endl;
std::cout << 256 << " " << is_small<256> << std::endl;
std::cout << 256 << " " << ism(256) << std::endl;
std::cout << 256 << " " << (256 <= 255) << std::endl;
}
When I compile it, it's ok. But when I run the thing, it simply seems to be broken.
[cpp11#hydra src]$ cat ~/bin/g14
#!/bin/bash
g++-52 -std=c++14 "${1}.C" -L$LIBPATH -o "$1"
[cpp11#hydra src]$ g14 konzept_small
[cpp11#hydra src]$ ./konzept_small
hallo welt
0 1
255 1
-4100000000 1
256 1 //1
256 0
256 0
[cpp11#hydra src]$
My problem is that:
the result for 256 and higher is wrong. See comment //1
there is no output of the template code on cerr
I started with a version without the cerr, but got only the wrong template result.
I removed a constexpr from the template, but no change.
So I added as last step the cerr to see whats wrong.
Any ideas?
You are not calling is_small<N>, but just printing out its address. You need to change your code to
std::cout << 0 << " " << is_small<0>() << std::endl;
std::cout << 255 << " " <<is_small<255>() << std::endl;
std::cout << -4100000000 << " " << is_small<-4100000000>() << std::endl;
std::cout << 256 << " " << is_small<256>() << std::endl;
Note the added (). Not sure why you are getting the output you are though, are you sure you are running the same code you posted?
is_small is a function you should add the parenthesis :
change
std::cout << 0 << " " << is_small<0> << std::endl;
to this
std::cout << 0 << " " << is_small<0>() << std::endl;
It worked fine for me with this change