in my c++ linux application I have this macro:
#define PRINT(format,arg...) printf(format,##arg)
I want to add a date and time to the beggining of the string that come to PRINT. (it is a log, so I want it at runtime, with variables)
how to change this macro in order to do it?
thanks
Do you want compile time or runtime added to the string? If the former:
#define PRINT(format,arg...) printf(__DATE__ ":" __TIME__ " " format,##arg)
will work most of the time.
Note that this will only work if invocations of PRINT only use a string literal for the format string. (ie, PRINT( "foo" ) will work, but PRINT( x ) where x is a variable will not).
If you want a runtime date and time, just append "%s" to the format and then add a call to a function that returns what you want before the arguments.
If you want local runtime date and can use boost.date_time
#define DATE_TODAY to_simple_string(day_clock::local_day())
#define PRINT(format,arg...) printf( (DATE_TODAY + ": " + format).c_str(), ##arg)
You can also use day_clock::universal_day() if you want UTC time.
Assuming that you want the compile time date and that you compiler has a __DATE__ macro that returns the date
#define PRINT(format,arg...) printf(__DATE__ ": " format,##arg)
If you want runtime date, then you can do something like that:
std::string format_current_time()
{
// format the time as you like and return it as an std::string
}
#define PRINT(format,arg...) printf("%s: " format, format_current_time.c_str(), ##arg)
If you need the current datetime, you have to implement a regular function to do what you ask, since it's impossible for a C macro to return the data you are looking for.
Remember that a C macro is replaced by the C preprocessor at compile time.
Related
I would like to trigger a python script from my C++ script. The python script is independent, I do not need to pass it anything from C++, I also do not need anything returned to C++.
I would also like to pause execution of the C++ script until the python script has finished.
I have tried the embedding solutions and the wrapping solutions offered online, but I am looking for something much simpler.
I have attempted the following.
include cstdlib
system("py "C:\path\python_script.py"");
This attempt has problems with the double quotation mark syntax.
I then attempted this to deal with the double quotation mark probem.
include cstdlib
system("py " + char(34) + "C:\path\python_script.py" + char(34));
I then received the error "expression must have integral or unscoped enum type". It seems as though you can't concatenate strings this way in C++?
For my final attempt, I tried to concatenate the string in pieces.
include cstdlib
string path1 = "py ";
string path2 = "C:\path\python_script.py";
string path = python_path1 + char(34) + python_path2 + char(34);
system(path);
I now receive the error "no suitable conversion function from "std::string" to "const char" exists".
Any help would be greatly appreciated.
As other answer tell you add \ to escape the " and also double escape your \ path separator :
system("py \"C:\\path\\python_script.py\"");
You can try system("py \"C:\path\python_script.py\"");.
This way you escape the quotation mark and can write it into a string.
Have a look at this post
Try string stream
#include <sstream>
std::stringstream ss;
ss << "py ";
ss << "\"C:\path\python_script.py\"";
system(ss.str().c_str());
So I'm working on a little project to get into C++, and part of that is reading and writing data to a file. I've chosen the simplest route I know of, which is turning the various attributes of the object into a string of integers. To be clear, I'm working with an object "Day" which has various attributes about my day (minutes slept, minutes exercised, etc.) I currently have the following snippet of code:
string Day::writeAsData()
{
// Writes the day as a condensed machine-readable format:
// {rawTime,busyMinutes,sleepMinutes,productivity,enjoyment,fatigue,weight,calories}
// e.g. {1444316982,645,360,7,4,5,180,0}
string dataString = "{"
+ to_string(rawTime) + ","
+ to_string(busyMinutes) + ","
+ to_string(sleepMinutes) + ","
+ to_string(productivity) + ","
+ to_string(enjoyment) + ","
+ to_string(fatigue) + ","
+ to_string(weight) + ","
+ to_string(calories)
+ "}";
return dataString;
}
to write the data in a clear machine-readable format. I'm working on a companion function to get the data out of a string and set the values of the Day object appropriately. I found the C++ String Toolkit Library, and I want to use its parse() function. However, adding
#include "strtk.hpp"
to my list of includes ends up throwing a wrench in the build. Taking that line out, I get a clean and successful build. However, adding that line results in
Error C4996 'std::_Fill_n': Function call with parameters that may be unsafe - this
call relies on the caller to check that the passed values are correct. To disable this
warning, use -D_SCL_SECURE_NO_WARNINGS.
in line 2811 of xutility. I don't use std::Fill_n anywhere in my code.
So far, I've found that the String Toolkit uses the Boost libraries, which I have placed in my include directory. I tried to add
#define D_SCL_SECURE_NO_WARNINGS 1
to my Day.cpp file and my Day.h file, but neither have done anything. I can't add it to xutility because the file is read only. How can I either disable the warning or fix the issue?
First, your #define is not correct, it should be:
#define _SCL_SECURE_NO_WARNINGS
More details here:
MSDN: _SCL_SECURE_NO_WARNINGS
And here:
What does "use -D_SCL_SECURE_NO_WARNINGS" mean?
Second, if you are using visual studio (and I assume you are) you can define _SCL_SECURE_NO_WARNINGS for your whole project using the project settings under Preprocessor Definitions
If I have a file that's meant to be required by other files, is it possible to get the absolute filepath of the file that's requiring it?
So if lib_file.cr has a macro that is meant to be called by the app_file.cr that imported it, can that macro discover the filepath to app_file.cr at compile time?
I tried stuff like this:
macro tester
puts __DIR__
puts __FILE__
end
But when invoked from the file doing the requiring, it gives nothing at compile time and this at runtime:
?
expanded macro: app_file
If I change the macro to this:
macro tester
{{puts __DIR__}}
{{puts __FILE__}}
end
It gives me this at compile time:
"/home/user/Documents/crystal_test/lib_file"
"/home/user/Documents/crystal_test/lib_file.cr"
So is there a trick to get the full path to app_file.cr inside lib_file.cr at compile time?
You can use default args with __FILE__ to get the file that is calling the macro.
macro tester(file = __FILE__)
{{puts file}} # Print at compile time
puts {{file}} # Print at runtime
end
Is it possible to store and display the date of when my project was compiled?
I'd like to print this date when the program starts in order to know which version is used. Currently, I am doing this by hand, which is rather cumbersome.
I am using Visual Studio 2010.
C++ specifies that there's a special preprocessor macro called __DATE__ that is a string literal of when the compilation happened. There's also a corresponding __TIME__ macro.
You can use at such:
const std::string compilation_date = __DATE__;
const std::string compilation_time = __TIME__;
...
std::cout << "This source file was compiled on date " << compilation_date
<< " and at the time " << compilation_time << '\n';
You can use the __DATE__ and __TIME__ macros - see "Predefined macros" here.
As a sample, something like this:
#include <iostream>
int main()
{
using namespace std;
cout << "Compiled on: " << __DATE__ << endl;
cout << "Compiled at: " << __TIME__ << endl;
}
You would modify the messages and use according to your needs.
You could even look to building it up into a larger macro or named variable.
#include <iostream>
const char* const COMPILED = __DATE__ " # " __TIME__;
int main()
{
using namespace std;
cout << "Compiled: " << COMPILED << endl;
}
If the "version" information is tied to a source control location or data (such as a commit number), it may also be an idea to include that data in the build via a build step or command line define of some sort. You should also consider the effect of incremental builds on the date and time. I'm assuming the "release" builds are not incremental based, or if so, there is "touch" on the file containing the date and time data.
There are TWO parts to this. The first one (already mentioned in the answers) is to use __DATE__. Unfortunately, this will just tell you the date of compilation for that Translation Unit. If you want the date of the last Visual Studio Build, you need to force a rebuild of the Translation Unit containing __DATE__
One simple solution to this is to always update the file time of that Translation Unit. Say you want Joachim's solution, then you create a separate builddate.cpp file with
const std::string compilation_date = __DATE__;
const std::string compilation_time = __TIME__;
In the post build step, call copy /b builddate.cpp+,,. This means that after every build, the builddate.cpp file becomes newer than the executable and will be recompiled on the next build.
On Linux you'd use touch for this.
Your question shows that you are not using version control system. You should, there are no excuses like "my project too small I'll do it later when will work on something bigger" or "it is too complex". VCS is must use for every developer, when you start to use it you will not imagine how you lived before without it. So when you start to use VCS your question will be "how to put comit or tag version into source?" For example on svn you can use:
const char *version = "$Id:$";
and svn will change it to current commit version. For other VCS systems solution could be different but close, as this problem is very common.
There is a macro called
__DATE__
which resolves to something like "Apr 1 2015". One can just use that. It is a standard predefined macro.
__ DATE __ :
This macro expands to a string constant that describes the date on which the preprocessor is being run. The string constant contains eleven characters and looks like "Feb 12 1996". If the day of the month is less than 10, it is padded with a space on the left. If GCC cannot determine the current date, it will emit a warning message (once per compilation) and DATE will expand to "??? ?? ????". https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
However, this solution lacks formatting. Of course, you can parse it, but maybe there is an easier, more C++ like solution.
I'm hoping to add a little functionality to a Log File system for a project I'm working on. For my LogError() calls, I would like to include the function the error occurred in. I'm wondering if there's a way that I can access the name of the function that called LogError() so I can programmatically access that information to add it to the log.
For example:
bool Engine::GraphicsManager::Initialize(const HWND i_hWindow_main)
{
if ( !InitializeWindow( i_hWindow_main ) )
{
Engine::LogManager::Instance().LogError(L"GraphicsManager::Initialize - Unable to initialize graphics window");
return false;
}
Engine::LogManager::Instance().LogMessage(L"Graphics window initialized successfully");
/* SNIP */
initialized = true;
return true;
}
In the above example, I'd like LogError() to be able to determine that it was called from GraphicsManager::Initialize() and output (at least part of) that function's name instead of putting that in everywhere by hand.
EDIT: I should have mentioned that my LogError() function (and the other logging functions) are essentially wrappers for vfwprintf_s() so they can take variable length argument lists. While I like the "use a macro" suggestions, I'm not sure how to tackle that potential issue (which is likely another question).
Is this still reasonable/possible?
Thanks!
You could add an argument for the function name, and pass in the __FUNCTION__ macro: http://msdn.microsoft.com/en-us/library/b0084kay%28v=vs.80%29.aspx
And you could also define a macro that will automatically replace ...log...() with ...log...(__FUNCTION__).
These are predefined macros and part of the C/C++ standard which you can use:
__FILE__ __LINE__
They are explained here
Make a Logging macro
EDIT: Some fixes to deal with wide characters
//support macros
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define STRINGIZE(x) #x
#define __WFILE__ WIDEN(__FILE__)
#define __WFUNCTION__ WIDEN(__FUNCTION__)
#define __WLINE__ WIDEN( STRINGIZE(__LINE__) )
// logging macro
#define LOG(msg) Engine::LogManager::Instance().LogError(__WFILE__ L"::" __WFUNCTION__ L":" __WLINE__ L" - " msg)
Use it like this
if( error ) { LOG(L"Error!"); }
logs
File.cpp::Function:Line - Error!
This works by using C-style string concatenation. "aa" "bb" -> "aabb" along with some operator pasting to put L before "astring". It uses the __FILE__, __FUNCTION__, and __LINE__ macros to report where the error was logged from. __LINE__ is translated into a string with the STRINGIZE macro. Due to crappy compliance with the standard, BOOST_PP_STRINGIZE is recommended if you plan on using boost anyway.