Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I've gone over many questions with the same or similar titles, I have changed the code in so many ways I can't even count.... I have an interesting problem.
I have a class for logging that is extremely simple and just writes stuff into a file. The exact same code works in the constructor, but will not work in the member function. I'm stripping out some irrelevant code, the rest is:
private:
std::string logfile_path_;
std::string program_name_;
std::string GetTimestamp() {
timeval tv;
gettimeofday(&tv, NULL);
char cTimestamp[24];
strftime(cTimestamp, sizeof(cTimestamp), "%F %T", std::localtime(&tv.tv_sec));
sprintf(&cTimestamp[19], ".%03d", (tv.tv_usec / 1000)); // write the miliseconds (microseconds/1000) into cTimestamp starting at the 20th character. %03d == pad with 0, for a minimum length of 3, an integer.
return cTimestamp; // function returns std::string so this will be implicitly cast into a string and returned.
}
public:
int log_level_;
SrxDsLog(std::string Logfile_path, std::string program_name, int log_level) {
log_level_ = log_level;
program_name_ = program_name;
logfile_path_ = Logfile_path;
std::ofstream logfile(logfile_path_.c_str(), std::ios::out | std::ios::app);
std::cout << "Logger started, Log file: " << logfile_path_ << std::endl;
logfile << "Logger started, Log file: " << logfile_path_ << std::endl;
return;
}
void WriteLog(std::string Log_message, int Severity = LOG_CRITICAL, std::string Function_name = "") {
if (Severity >= log_level_) {
std::cout << GetTimestamp() << "|" << program_name_ << "|" << Function_name << "|" << GetSeverity(Severity) << "|" << Log_message << std::endl;
std::ofstream logfile(logfile_path_.c_str(), std::ios::out | std::ios::app);
logfile << GetTimestamp() << "|" << program_name_ << "|" << Function_name << "|" << GetSeverity(Severity) << "|" << Log_message << std::endl;
}
}
The question is why is it working in the constructor, but the exact same code is not working in the member function. The std::cout is writing the exact same log message I want, but it's not appearing in the file. The file contains a single line every time the program is run.
In an amazingly unsatisfying turn of events I voted to close my question.
The problem was apparently caused by undefined behavior in unrelated code. And that because I did something that's defined in C++11 but is not in C++03. Apparently you can't call constructors from constructors in C++03....
Because of that, and because the question didn't include the code that was actually at fault, the question seems incredibly bad.
Please close.
int log_level_;
The constructor fails to initialize this class member.
Subsequently, the comparison with this class member results in undefined behavior.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 months ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
This seems like a simple thing to me, but I have an entity class:
class Entity
{
private:
std::string m_Name;
public:
int x = 0, y = 0;
Entity() : m_Name("Undefined Entity") {
std::cout << m_Name << " Created!\n";
}
Entity(const std::string& name) : m_Name(name) {
std::cout << m_Name << " Created!\n";
}
~Entity() {
std::cout << m_Name << " Destroid\n";
}
const std::string GetName() { return m_Name; }
void PrintCords() { std::cout << x << ' , ' << y << '\n'; }
};
and in my main function I run the PrintCords function:
int main(void)
{
std::unique_ptr<Entity> j = std::make_unique<Entity>("Jeff");
std::cout << j->GetName() << '\n';
j->PrintCords();
}
Yet, when I run the program, I get seemingly random numbers:
021084480
You should compile with -Werror. This turns your warnings into errors. When you do this, you will see the following error:
prog.cpp:25:43: warning: multi-character character constant [-Wmultichar]
void PrintCords() { std::cout << x << ' , ' << y << '\n'; }
^~~~~
Which should indicate to you that something is wrong. If you change this to a string literal:
void PrintCords() { std::cout << x << " , " << y << '\n'; }
---> ^ ^
Then everything will be ok.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am receiving the error message 'struct std::string' has no member named 'c_string' in my code. I am basing the structure of this code off of a code in my textbook that successfully wrote a code with my compiler. What syntax errors could be causing this particular error? (it's on line 11)
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<iomanip>
using namespace std;
int main()
{
string payroll = "table.dat";
ofstream MyCout;
MyCout.open(payroll.c_string());
if (MyCout.fail())
{
cout<<"Your file was not found";
exit(1);
}
MyCout<<setiosflags(ios::fixed)
<<setiosflags(ios::showpoint)
<<setprecision(2);
MyCout << "B Caldwell 555-88-2222"<<17.32<<37<<endl
<< "Next Line"<<0.00<<00<<endl;
<< "Next Line"<<0.00<<00<<endl;
MyCout.close();
cout<<"The file "<<payroll<<" has been successfully written"<<endl;
system ("Pause");
return 0;
}
I'm not sure if this helps or not, but here is the code that I am basing it off of
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<iomanip>
using namespace std;
int main()
{
string filename = "prices.dat";
ofstream outFile;
outFile.open(filename.c_str());
if (outFile.fail())
{
cout << "The file was not successfully opened" << endl;
exit(1);
}
outFile << setiosflags(ios::fixed)
<< setiosflags(ios::showpoint)
<< setprecision(2);
outFile << "Mats " << 39.95 << endl
<< "Bulbs " << 3.22 << endl
<< "Fuses " << 1.08 << endl;
outFile.close();
cout << "The file " << filename << " has been successfully written."<<endl;
return 0;
}
std::string has no function or member called c_string, hence the exact compiler error. You can find plenty of information online about what members and functions are available to call on standard library objects, for instance here.
If you look closer at the code you're referencing, you'll see you meant to use c_str() instead.
Their code:
ofstream outFile;
outFile.open(filename.c_str());
Your code:
ofstream MyCout;
MyCout.open(payroll.c_string());
The solution:
ofstream MyCout;
MyCout.open(payroll.c_str());
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.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
i have a easy struct
struct Test {
std::vector<int> values;
int value;
}
with overloaded << operator
inline std::ostream& operator<<(std::ostream& p, const Test& t)
{
p << "test: ";
for(size_t i = 0; i < t.values.size(); i++) {
std::cout << t.values[i] << " ";
}
p << " value: " << t.value << std::endl;
return p;
}
this works fine when i use the default output. But when i am using my boost logge, shown here Different boost log sinks for every class, it print the values inside my console and the rest inside my file. Anyone has an idea what happens there?
std::cout << t.values[i] << " ";
should be
p << t.values[i] << " ";
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I was wondering, and some people with a lot more knowledge than me will probably know the answer :
Why isn't the C (in my case its for C++) preprocessor more complete ?
What I mean is why couldn't we use for example C++ as the preprocessor language ? It would allow us to do so much more about classes, generate dynamic code etc...
Ideally I would want to call a C++ function just like a preprocessor macro, with a concrete example, I would like to do things like:
#void generateVariable(std::string type, std::string name) {
# if (name[0] == 'p')
# cout << "protected:" << endl << type << " " << name << ";" << endl;
# if (name[0] == 'm')
# cout << "public:" << endl << type << " " << name << ";" << endl;
# std::string prefix = name;
# prefix.erase(2, npos);
# name.erase(0,2);
# name[0] = toupper(name[0]);
# cout << "public:" << endl << type << "get" << name << "() const { return " << prefix+name << "; }" << endl;
#}
So that I could call
class A {
generateVariable(static const int, p_age)
}
And it would generate
class A {
protected:
static const int p_age;
public:
static const int getAge() const { return p_age; }
}
Are there actually ways to do this kind of thing, whithout parsing the whole file with a scripting language and rewriting it ?
The preprocessor actually can do this (though I wouldn't recommend to do so):
#define generateVariable(__type__, __name__) \
protected: __type__ __name__; \
public: __type__ get##__name__() { return __name__; }
class A {
generateVariable(static const int, p_age);
}
get##__name__() will expand to getp_age() though ...