I had been seeing some code snippet from someone as shown below:
before changed:
void pal::type3_message::debug_print(std::ostream & out) const
{
out << "### type3_message:" << '\n'
<< pal::as_hex_dump(as_bytes())
<< "lm_response = " << pal::as_hex_string(lm_response_)
<< "\nnt_response = " << pal::as_hex_string(nt_response_)
<< "\ndomain = " << domain_
<< "\nuser = " << user_
<< "\nworkstation = " << workstation_
<< "\nsession_key = " << pal::as_hex_string(session_key_)
<< std::hex << std::setw(8) << std::setfill('0')
<<"\nssp_flags = " << ssp_flags_;
}
after changed:
std::string pal::type3_message::debug_print() const
{
std::ostringstream buf;
buf << "### type3_message:" << '\n'
<< pal::as_hex_dump(as_bytes())
<< "lm_response = " << pal::as_hex_string(lm_response_)
<< "\nnt_response = " << pal::as_hex_string(nt_response_)
<< "\ndomain = " << domain_
<< "\nuser = " << user_
<< "\nworkstation = " << workstation_
<< "\nsession_key = " << pal::as_hex_string(session_key_)
<< std::hex << std::setw(8) << std::setfill('0')
<<"\nssp_flags = " << ssp_flags_;
return buf.str();
}
I am not very sure of the change above, is anyone can tell me how that should happened and the deep significance of it ? look forward for response and appreciate of it.
I'm not exactly sure what you are asking, so I'm just explaining what the code sample does and what the major difference between both functions is:
void pal::type3_message::debug_print(std::ostream & out) const
This function writes a message to an output stream that is referenced by the out parameter. It has no return value.
std::string pal::type3_message::debug_print() const
This function seems to output the same message but instead of writing it to a stream, it stores the message in a string. This string is returned by the function.
The implementation of both functions looks very similar because the 2nd function uses a temporary std::ostringstream internally. This is a stream that exist in memory only. In contrast, you could pass a file stream like std::ofstream to the 1st function.
Please clarify your question if you want to know more.
can tell me how that should happened and the deep significance of it?
The first method receives an std::ostream& parameter, and streams more than 10 different chunks of text into it.
The second method streams the same 10 chunks of text into a locally created (automatic var) std::ostringstream. This concatenates the chunks prior to returning the string.
Possible usage examples (to achieve same output on std::cout):
pal::type3_message::debug_print(std::cout);
std::cout << std::endl;
and
std::cout << pal::type3_message::debug_print() << std::endl;
I prefer the std::stringstream approach, but I have used both.
In the first method, the thread can be 'interrupted' in more places (between the 10) with possible impact to the not private stream effort. Does this cause an issue? I have not investigate on a desktop.
The second method completes the concatenation, then returns a string. All the previous interruption points are still there, but none affect the delivery to std::cout, a shared stream destination. Note there is still 1 (or maybe 2) interruptions places in this path (to append the string). Still, this is probably less likely to produce visible issues.
In an embedded system I once worked on, because of drivers it had, the second method was clearly better (in terms of thread interruptions during use) and appeared it did not need mutex guard on the out channel.
On Ubuntu, I have added mutex guard's to access std::cout ... to avoid the 'inter-mixed' text, though I did not confirm that the change-described-in-this-post could have been sufficient.
I have an in-ram-log with a round-robin-buffer, and that shared resource has a mutex guard. Never any problems with multiple threads contributing to the same log.
Note: Per the post Question, I see no difference in either stream effort with respect to std::hex or std::setw, both are used identically.
update per July 2, comment
I agree that 'after' is what I prefer.
I do not recognize the phrase "do not mess with borrowed things". I looked and decided Google's report on this phrase had no software relevance.
But it reminded me of a possibly related caution I have heard, "code is like an onion". The guy who repeated this to me (obsessively) resisted 'fixing' things (a crash for example) because, I surmise, he worried that any changes might break 'behaviour' in an undetectable manner. Thus, he worked through 'all the onion layers' until he was sure nothing bad would happen, before he committed a code change. 'Paralysis by analysis' comes to mind.
I am, apparently, much more tolerant to trying something else (and test, test, test...) That crash was easy to fix, and the crash certainly held up progress on understanding the deeper layers of the onion.
Related
I wanted to create objects from the class “takeSnapshots” that would learn, upon their instantiation, the name of another object from the class “lock” that they could query later as the state of the “lock” object changes. I can think of multiple ways of letting the object from class “takeSnapshots” know which object it is to query (like including the name of the “lock” object as part of the call to its member functions). But, I thought it better to take care of the relation in the beginning and not worry later if I am calling the correct object combinations.
The included code shows stripped down versions of the two classes and example instantiations created in main.
I have included the outputs on each line following their respective couts.
What I expected was that the constructor of “takeSnapshots” would store away the address of the “lock” object. Then I could use it later when taking a snapshot. You can see that what gets stored away (at least when I use it to get numWheels) is a few addresses off from the address that the “lock” object thinks it has for numWheels.
I am mostly interested in knowing why this code does not work the way I expect, i.e, if this is not a good architectural idea, that is one thing. But with the behavior I’m seeing here, I’m clearly not ready to use pointers in anything complicated and I don’t want to give up on the basic architecture just because of erroneous implementation. Any help would be greatly appreciated.
// simpleTest.cpp : Demonstrates problem I'm having understanding
// pointer to an object.
#include "stdafx.h"
#include<iostream>
using namespace std;
class lock {
public: //Just while I run a test.
int numWheels;
lock(int numW) {
numWheels = numW;
cout << " \n In \"lock\" constuctor, address and value of numWheels
" << &numWheels << " " << numWheels << endl;
} //Values from console: 0034F874 and 4
};
class takeSnapshots {
lock* localLock;
public:
takeSnapshots(lock myLock) {
localLock = &myLock;
cout << " \n In \"takeSnapshots\" constuctor, address and value of
numWheels " << &localLock->numWheels << " "
<< localLock->numWheels << endl;
//Values from console: 0034F794 and 4 "Same value, but not the same
//address as expected from "lock."
}
void takeASnapSnapshot() {
cout << " \n When taking a snapshot, address and value of numWheels
" << &localLock->numWheels << " " << localLock->numWheels <<
endl;
//Values from console: 0034F794 and 2303449 "No longer even the
// same value as expected from "lock."
}
};
int main()
{
lock yourLock(4);
takeSnapshots myShots1(yourLock);
cout << " \n In main (from \"yourLock\"), address and value of
numWheels " << &yourLock.numWheels << " " << yourLock.numWheels <<
endl;
//Values from console: 0034F874 and 4 "Still the same values as set
//in the constructor of "lock."
//Take a picture
myShots1.takeASnapSnapshot();
return 0;
}
I don't know exactly how to define what I am searching, but, here I go:
Since the library libjsoncpp exists and lets us hold a value in an object that is "json based", which means, an integer, an unsigned number, double, string or null... (also arrays and objects that can be seen -or I perceive- as pointer based objects to other objects),
... is there any kind of library in which we could operate with those data, more or less as we do in javascript?
#include "somemagiclib.h"
magicnamespace::jsonlike_o value1=10;
int integervalue=15;
magicnamespace::jsonlike_o value2="hello_world";
std::string anything="anything";
magicnamespace::jsonlike_o value3="10.3";
magicnamespace::jsonlike_b result;
value3=value2+value1;
std::cout << "value3 is: " << value3.asString() << std::endl;
/*value3 is: 21*/
std::cout << (value2+value1).asString() << std::endl;
/*hello_world10*/
std::cout << (value1+value3).asString() << std::endl;
/*20*/
std::cout << (value3+value1).asString() << std::endl;
/*10.310*/
std::cout << (value1<value3).asString() << std::endl;
/*true*/
std::cout << (value1+integervalue).asString() << std::endl;
/*25*/
std::cout << (value1+anything).asString() << std::endl;
/*18*/
std::cout << (value1>=integervalue).asString() << std::endl;
/*false*/
std::cout << (value2+integervalue).asString() << std::endl;
/*hello_world15*/
std::cout << (value2+anything).asString() << std::endl;
/*hello_worldanything*/
We could easily reach to the ask "what for?" (...or even "wtf for?"). In fact, I am working on a project that requires a part of json processing to compare values that are obtained from part based ports transmitting in serial protocols, compared with values that are obtained from json based configured files.
Being able to code or preview the future scenarios is becoming difficult, since we also have to preview incoming values from JsonRPC based objects, so the code may become expensive to generate or to maintain.
Do you know if there's any kind of library that implements this kind of "non-typed" type in C++?
In case of not knowing, do you think that this kind of library deserves the efforts to be created?
Thank you very much for your attention.
Look into crow c++. its not just json stuff, its pretty much flask for c++. might be useful. it's also just a header file, so no installation etc is needed
I have to rewrite a logging system in C++ as part of project requirements (everything has to be C++ instead of C now), and there are a number of ways in which we log things like mathematical data and pointer addresses. It is fairly common to see a log like:
log("%3.4f %d %zp %5.8f", ...);
In C++, using cout instead of printf, it seems a bit more of an involved process to setup such a logging format, eg, taking the following snippet from C++ Primer Plus (Prata):
ios_base::fmtflags initial;
initial = os.setf(ios_base::fixed); // save initial formatting state
os.precision(0);
os.setf(ios::showpoint);
os.precision(1);
os.width(12);
This looks like it will set the width and precision for all floating point items in the argument list, and won't allow me to have different values for different variables.
Can cout even generate such a string in a simple manner with just one line of code, or should I use sprintf to prepare my strings and then feed them to cout?
Thanks!
Question the requirements!
printf works fine in C++, proper use of compiler warnings prevent type inconsistencies. The C++ formatting alternative is too complicated and error prone: it is so easy to leave the stream formatting in a different state than upon entry.
If you really need to use cout, use snprintf() to format the log entry and shift the formatted string to cout.
Can cout even generate such a string in a simple manner with just one
line of code, or should I use sprintf to prepare my strings and then
feed them to cout?
I agree that sprintf() is not C++. It merely provides some manner of backward compatibility ... i.e. it has been provided specifically so that you can post-pone the conversion (of c to c++) and that technical debt to later in your schedule.
Here is a code sample from when I 'fixed' a log to be C++. (I left in the sprintf() to help document the new C++ code.)
//retVal = ::sprintf(buff1, "%08llx %2d:%02d:%02d, %05llu.%03llu: ",
// a_pid, hr, min, sec, (ms_of_day / 1000), (rt_ms % 1000));
// use stringstream formatting, not sprintf
buff1 << std::dec << std::setfill('0') << std::setw(8) << a_pid << " "
<< std::setfill('0') << std::setw(2) << hr << ":"
<< std::setfill('0') << std::setw(2) << min << ":"
<< std::setfill('0') << std::setw(2) << sec << ", "
<< std::setfill('0') << std::setw(5) << (ms_of_day / 1000)
<< "."
<< std::setfill('0') << std::setw(3) << (ms_of_day % 1000)
<< ": ";
I only had to do this once.
In a lot of ways, I do not miss the 'unsafe-type' style of sprintf.
If there is something special you do often, you might also consider creating something like the following.
std::string ssprintf0x08x(std::string label, void* ptr)
{
std::stringstream ss;
ss << label << "0x"
<< std::hex << std::internal << std::setw(8)
<< std::setfill('0')
<< reinterpret_cast<uint64_t>(ptr);
return (ss.str());
}
I only had to implement this one time.
Answer to question:
Can cout even generate such a string in a simple manner with just one
line of code?
Yes. Of course.
C++ stream output has a learning curve, but it leads you to a type-safe approach for text output.
And, perhaps you are realizing, one line of code can be quite long.
I am experiencing a few problems with Crypto++'s Integer class. I am using the latest release, 5.6.2.
I'm attempting to convert Integer to string with the following code:
CryptoPP::Integer i("12345678900987654321");
std::ostrstream oss;
oss << i;
std::string s(oss.str());
LOGDEBUG(oss.str()); // Pumps log to console and log file
The output appears to have extra garbage data:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
I get the same thing when I output directly to the console:
std::cout << "Dec: " << i << std::endl; // Same result
Additionally, I cannot get precision or scientific notation working. The following will output the same results:
std::cout.precision(5); // Does nothing with CryptoPP::Integer
std::cout << "Dec: " << std::setprecision(1) << std::dec << i << std::endl;
std::cout << "Sci: " << std::setprecision(5) << std::scientific << i << std::endl;
On top of all of this, sufficiently large numbers breaks the entire thing.
CryptoPP::Integer i("12345");
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i *= i;
}
std::cout << i << std::endl; // Will never finish
Ultimately I'm trying to get something where I can work with large Integer numbers, and can output a string in scientific notation. I have no problems with extracting the Integer library or modifying it as necessary, but I would prefer working with stable code.
Am I doing something wrong, or is there a way that I can get this working correctly?
I'm attempting to convert Integer to string with the following code:
CryptoPP::Integer i("12345678900987654321");
std::ostrstream oss;
oss << i;
std::string s(oss.str());
LOGDEBUG(oss.str()); // Pumps log to console and log file
The output appears to have extra garbage data:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
I can't reproduce this with Crypto++ 5.6.2 on Visual Studio 2010. The corrupted output is likely the result of some other issue, not a bug in Crypto++. If you haven't done so already, I'd suggest trying to reproduce this in a minimal program just using CryptoPP::Integer and std::cout, and none of your other application code, to eliminate all other possible problems. If it's not working in a trivial stand-alone test (which would be surprising), there could be problems with the way the library was built (e.g. maybe it was built with a different C++ runtime or compiler version from what your application is using). If your stand-alone test passes, you can add in other string operations, logging code etc. until you find the culprit.
I do notice though that you're using std::ostrstream which is deprecated. You may want to use std::ostringstream instead. This Stack Overflow answer to the question "Why was std::strstream deprecated?" may be of interest, and it may even the case that the issues mentioned in that answer are causing your problems here.
Additionally, I cannot get precision or scientific notation working.
The following will output the same results:
std::cout.precision(5); // Does nothing with CryptoPP::Integer
std::cout << "Dec: " << std::setprecision(1) << std::dec << i << std::endl;
std::cout << "Sci: " << std::setprecision(5) << std::scientific << i << std::endl;
std::setprecision and std::scientific modify floating-point input/output. So, with regular integer types in C++ like int or long long this wouldn't work either (but I can see that especially with arbitrary-length integers like CryptoPP:Integer being able to output in scientific notation with a specified precision would make sense).
Even if C++ didn't define it like this, Crypto++'s implementation would still need to heed those flags. From looking at the Crypto++ implementation of std::ostream& operator<<(std::ostream& out, const Integer &a), I can see that the only iostream flags it recognizes are std::ios::oct and std::ios::hex (for octal and hex format numbers respectively).
If you want scientific notation, you'll have to format the output yourself (or use a different library).
On top of all of this, sufficiently large numbers breaks the entire
thing.
CryptoPP::Integer i("12345");
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i *= i;
}
std::cout << i << std::endl; // Will never finish
That will actually calculate i^(2^16) = i^65536, not i^16, because on each loop you're multiplying i with its new intermediate value, not with its original value. The actual result with this code would be 268,140 digits long, so I expect it's just taking Crypto++ a long time to produce that output.
Here is the code adjusted to produce the correct result:
CryptoPP::Integer i("12345");
CryptoPP::Integer i_to_16(1);
// Calculate i^16
for (int x = 0; x < 16; x++)
{
i_to_16 *= i;
}
std::cout << i_to_16 << std::endl;
LOGDEBUG(oss.str()); // Pumps log to console and log file
The output appears to have extra garbage data:
12345678900987654321.ÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
I suspect what you presented is slighty simplified from what you are doing in real life. I believe the problem is related to LOGDEBUG and the ostringstream. And I believe you are outputting char*'s, and not string's (though we have not seen the code for your loggers).
The std::string returned from oss.str() is temporary. So this:
LOGDEBUG(oss.str());
Is slighty different than this:
string t(oss.str());
LOGDEBUG(t);
You should always make a copy of the string in an ostringstream when you intend to use it. Or ensure the use is contained in one statement.
The best way I've found is to have:
// Note: reference, and the char* is used in one statement
void LOGDEBUG(const ostringstream& oss) {
cout << oss.str().c_str() << endl;
}
Or
// Note: copy of the string below
void LOGDEBUG(string str) {
cout << str.c_str() << endl;
}
You can't even do this (this one bit me in production):
const char* msg = oss.str().c_str();
cout << msg << endl;
You can't do it because the string returned from oss.str() is temporary. So the char* is junk after the statement executes.
Here's how you fix it:
const string t(oss.str());
const char* msg = t.c_str();
cout << msg << endl;
If you run Valgrind on your program, then you will probably get what should seem to be unexplained findings related to your use of ostringstream and strings.
Here is a similar logging problem: stringstream temporary ostream return problem. Also see Turning temporary stringstream to c_str() in single statement. And here was the one I experienced: Memory Error with std:ostringstream and -std=c++11?
As Matt pointed out in the comment below, you should be using an ostringstream, and not an ostrstream. ostrstream has been deprecated since C++98, and you should have gotten a warning when using it.
So use this instead:
#include <sstream>
...
std::ostringstream oss;
...
But I believe the root of the problem is the way you are using the std::string in the LOGDEBUG function or macro.
Your other questions related to Integer were handled in Softwariness's answer and related comments. So I won't rehash them again.
I'm very new to programming in C++ but I'm trying to write some code which filters a specific word from a string and then takes a specific action. For some reason the code does not see the text inside the string.
printf("%s \n", data.c_str());
cout << data;
This shows absolutely nothing - meaning I cannot use .find or write it to a file.
printf("%s \n", data);
This shows exactly what I need.
I am writing the code into data with assembly:
mov data, EDX
Why is that I can only use the the last method?
Edit:
Data is initiated as:
std::string data;
If a pointer to a string is null all subsequent calls to cout
stop working
const char* s=0;
cout << "shown on cout\n";
cout << "not shown" << s << "not shown either\n";
cout << "by bye cout, not shown\n";
The two function calls are not equivalent, as \n at printf flushes the stream. Try with:
cout << data << endl;
Be sure you used
#include <string>
in your file header. With this in place you should be able to use
std::cout << data << endl;
with no issues. If you're using a global namespace for std you may not need the std::, but I'd put it anyway to help you debug a it faster and eliminate that as a possible problem.
In Short
You will have a problem with cout, if you don't put a linebreak at it's end!
In Detail
Try adding an endl to your cout (e.g. std::cout << data << std::endl), or use following instruction to activate "immediate output" for cout (without it needing a linebreak first).
std::cout << std::unitbuf;
Complete example:
std::cout << std::unitbuf;
std::cout << data;
// ... a lot of code later ...
std::cout << "it still works";
Sidenote: this has to do with output buffering, as the name unitbuf suggests (if you want to look up what is really happening here).
This way it is also possible to rewrite the current line, which is a good example, where you would need this ;-)
Practical example
using namespace std;
cout << "I'm about to calculate some great stuff!" << endl;
cout << unitbuf;
for (int x=0; x<=100; x++)
{
cout << "\r" << x << " percent finished!";
// Calculate great stuff here
// ...
sleep(100); // or just pretend, and rest a little ;-)
}
cout << endl << "Finished calculating awesome stuff!" << endl;
Remarks:
\r (carriage return) puts the curser to the first position of the line (without linebreaking)
If you write shorter text in a previously written line, make sure you overwrite it with space chars at the end
Output somewhere in the process:
I'm about to calculate some great stuff!
45 percent finished!
.. and some time later:
I'm about to calculate some great stuff!
100 percent finished!
Finished calculating awesome stuff!