I'm using a library called DS3231 by rinkydinkelectronics
Link: http://www.rinkydinkelectronics.com/library.php?id=73 (click on manual)
i'm trying to run the following code
String alarmTime = "08:52:00";
void loop(){
if (rtc.getTimeStr() == alarmTime){
alarmState = true;
}
}
but i get the following error:
exit status 1 no match for 'operator==' (operand types are 'char*' and
'String')
the library manual however says that the return value is a string so I don't see why this shouldn't work :(
Can someone help me fix this or tell me what might be wrong?
Thank you!
If understood your code right, you want to check whether both strings are equal. Because the standard library is not available in the Arduino IDE, you must choose a different way. Convert the C string (char*) to a String object.
Example:
if(String(rtc.getTimerStr()) == alarmTime) {
....
}
This should work.
You're trying to compare two different things with confusingly similar names. A string(C style string) is a null terminated char array. This is different from the String object. It's generally accepted that with extremely memory limited hardware such as the standard Arduino boards you should avoid the use of the String class if possible as it uses more memory and may cause memory fragmentation from dynamic memory allocation. Much better to use strings instead, which are actually pretty much just as easy to work with as String.
Your code using only strings:
char alarmTime[] = "08:52:00";
void loop() {
if (strcmp(rtc.getTimeStr(), alarmTime) == 0) {
alarmState = true;
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How Python can get binary data(char*) from C++ by SWIG?
I have a SWIG based C++ interface that can called from Python. There is a function in it, that has one std::string argument. It looks like this:
WrapperGet(const std::string& key);
If it is called from Python with a string argument that contains NUL character (e.g. binary data), then the std::string is truncated at the NUL character, and that is my problem, because it makes impossible to handle binary data.
What makes it interesting is that other way works perfectly:
std::string WrapperResult();
The string returned here can contain binary data without truncation. Has anybody any idea what has to be done?
UPDATE: I debugged the SWIG generated code and it turned out that the error was in the wrapper code on the C++ size: it used the c_str() member function of the std::string to get the string value.
Thanks for everybody's ideas and time!
I've had to deal with this in the past, and I just grabbed the std::string conversion template from SWIG and tailored it a bit to use PyString_FromStringAndSize when creating a Python string from a std::string and the std::string constructor that accepts a size argument when going the other way.
That was with a really old version of SWIG, though - I thought the builtin conversion template in newer versions had been updated to do that automatically. Is it possible the problem is on the C++ side? (e.g. as in Mark Tolonen's examples, where the first example is truncated due to the embedded NULL in the constructor call without a size argument).
It is probably how the strings are constructed. Consider:
string blah(const string& x)
{
string y("abc\x00def");
return x + y;
}
string blah2(const string& x)
{
string y("abc\x00def",7);
return x + y;
}
Calling these from Python:
>>> import x
>>> x.blah('abc\x00def')
'abc\x00defabc'
>>> x.blah2('abc\x00def')
'abc\x00defabc\x00xyz'
The constructor for std::string(const char*) stops at the NULL, but clearly SWIG can pass in and return strings with a NULL in them.
a C++ noob here. I am trying to tweak some code, with the following key lines (meaning they are not the only ones, but they are the only ones that should matter for this question). By the way, I am using Visual Studio 2010 C++ compiler on Windows.
CMap<ATL::CAtlString,LPCTSTR,UINT,UINT> mapForDuplicates; // "dict" definition
ATL::CAtlString strDescription = ... // let's just say it gets set to a value.
UINT nFound = 0; // What is this for???
BOOL bFound = mapForDuplicates.Lookup(strDescription, nFound);
mapForDuplicates[strDescription] = 1;
Now ... I really do not want to use the UINT here, as bool is all I really need. However, I could not figure out what all of the arguments for the CMap constructor really are. When using C#, all I have to specify is the type of the key and the type of the value. The fact that ATL::CAtlString does not match LPCSTR really confuses me. What exactly are KEY, ARG_KEY, VALUE, and ARG_VALUE? Why do I need all four and can all four be different? Thanks.
...
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>
class CMap : public CObject
...
Note: I could use std::map here instead(although I have not used it either); the only non-negotiable is ATL::CAtlString - I have to use this type. Let me know if you have questions.
IIRC the four args to the template are there so you can throw one type in and get another (const) type back. Here it throws in CAtlStrings, but it'll get back LPCTSTR. Often you just specify the same to types twice (e.g. int, int, float, float for a map of ints -> floats).
Grr, that extra L really irks me nowadays, it was great for 16-bit Windows but nowadays... PCSTR is all that's needed. 'L' is the useless appendix of Windows programming.
nFound is something coming out of the map, the map maps to UINT so nFound is a UINT.
Start with the docs for the class =- there is a ref to a sample here too
http://msdn.microsoft.com/en-us/library/s897094z(VS.71).aspx
By the way, the following pseudo-sample did the trick for me.
std::set<CAtlString> setOfDescriptions;
for each(...)
{
CAtlString strDescription = GetDescription();
if (setOfDescriptions.find(strDescription) != setOfDescriptions.end())
{
// Remove a duplicate.
}
setOfDescriptions.insert(strDescription); // Mark as seen.
}
I have to classes, an Executer with these methods:
Executer()
struct Execute(string s)
Lookup(string name, int module, int num, ...)
and a Parser:
Parser()
struct Parse(string s)
The Exectuers Execute method calls the Parsers Parse method. The Parser then chucks the string into smaller bits (it explodes the string on the ;-sign) and returns a struct to the Execute method. This struct it uses to call the Lookup method.
The struct that the Parse returns holds some standard information:
An command name
A senderId (a username, a mac address and a password)
A variable number of arguments
And that is my problem. The Lookup method take variable arguments, but how do I handle the the hand over of these variable arguments by the struct? Im not an expert in C and C++. Should I mass the two classes togheter? So the Parser method could call the Execute method, sparing the struct away.
Or maybe there is a way of parsing an unknown variable of arguments at runtime? By some sort of array?
EDIT
I cant use the STL library from C++. I only use the C++ class and virtual feature. Im writing to an compiler where Im restricted to use almost all of the C libraries + the magic skills of C++ (virtual and class). SOory for not telling that right away.
EDIT 2
Im writing code to an embedded system and thereby using avr-gcc to compile my code. Thats why I cant use STL. The avr-gcc doesnt support this.
Use std::vector<> or a simular container that can hold an arbitrary number of entries.
struct {
std::string commandName;
sender_t senderId;
std::vector<arg_t> arguments;
};
Edit: oh, you can't use std::vector. In that case: use an array and store the length:
struct {
const char* commandName;
sender_t senderId;
int argumentCount;
int maxArgumentCount; // you might not need this
arg_t* arguments; // pointer to array of (at least) argumentCount elements.
};
Use malloc() or new() to create the array for the arguments.
I would suggest to wrap the argumentCount, maxArgumentCount and arguments in a separate class, which can handle the malloc/new and free/delete as well. This will make it easier to prevent memory leaks.
In the end, you'll have written your own vector_of_arg_t class, so maybe have a look at some basic vector implementation. There must be tutorials on that on the web.
You could declare your Lookup method as follows:
void Lookup(string name, int module, int num, std::vector<std::string> &args);
By storing the variable arguments in an args array, you can have as many as you want.
See
Q: How can I write a function which takes a variable number of arguments and passes them to some other function (which takes a variable number of arguments)?
A: In general, you cannot. Ideally, you should provide a version of that other function which accepts a va_list pointer.
Suppose you want to write a faterror function which will print a fatal error message, then exit. You might like to write it in terms of the error function of question 15.5:
void faterror(const char *fmt, ...)
{
error(fmt, what goes here? );
exit(EXIT_FAILURE);
}
but it's not obvious how to hand faterror's arguments off to error.
<snip>
Read on at
http://c-faq.com/varargs/handoff.html
For a specific example, consider atoi(const std::string &). This is very frustrating, since we as programmers would need to use it so much.
More general question is why does not C++ standard library reimplement the standard C libraries with C++ string,C++ vector or other C++ standard element rather than to preserve the old C standard libraries and force us use the old char * interface?
Its time consuming and the code to translate data types between these two interfaces is not easy to be elegant.
Is it for compatible reason,considering there was much more legacy C code than these days and preserving these C standard interfaces would make translation from C code to C++ much easier?
In addition,I have heard many other libraries available for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?
PS: Considering much more answers to the first specific question, I edit a lot to clarify the question to outline the questions that I am much more curious to ask.
Another more general question is why do not STL reimplementate all the standard C libraries
Because the old C libraries do the trick. The C++ standard library only re-implements existing functionality if they can do it significantly better than the old version. And for some parts of the C library, the benefit of writing new C++-implementations just isn't big enough to justify the extra standardization work.
As for atoi and the like, there are new versions of these in the C++ standard library, in the std::stringstream class.
To convert from a type T to a type U:
T in;
U out;
std::stringstream sstr(in);
sstr >> out;
As with the rest of the IOStream library, it's not perfect, it's pretty verbose, it's impressively slow and so on, but it works, and usually it is good enough. It can handle integers of all sizes, floating-point values, C and C++ strings and any other object which defines the operator <<.
EDIT:In addition,I have heard many other libraries avaliable for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?
Boost has a boost::lexical_cast which wraps std::stringstream. With that function, you can write the above as:
U out = boost::lexical_cast<U>(in);
Even in C, using atoi isn't a good thing to do for converting user input. It doesn't provide error checking at all. Providing a C++ version of it wouldn't be all that useful - considering that it wouldn't throw and do anything, you can just pass .c_str() to it and use it.
Instead you should use strtol in C code, which does do error checking. In C++03, you can use stringstreams to do the same, but their use is error-prone: What exactly do you need to check for? .bad(), .fail(), or .eof()? How do you eat up remaining whitespace? What about formatting flags? Such questions shouldn't bother the average user, that just want to convert his string. boost::lexical_cast does do a good job, but incidentally, C++0x adds utility functions to facilitate fast and safe conversions, through C++ wrappers that can throw if conversion failed:
int stoi(const string& str, size_t *idx = 0, int base = 10);
long stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);
long long stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);
Effects: the first two functions call strtol(str.c_str(), ptr, base), and the last three functions
call strtoul(str.c_str(), ptr, base), strtoll(str.c_str(), ptr, base), and strtoull(str.c_str(), ptr, base), respectively. Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: the converted result.
Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if the converted value is outside the range of representable values for the return type.
There's no good way to know if atoi fails. It always returns an integer. Is that integer a valid conversion? Or is the 0 or -1 or whatever indicating an error? Yes it could throw an exception, but that would change the original contract, and you'd have to update all your code to catch the exception (which is what the OP is complaining about).
If translation is too time consuming, write your own atoi:
int atoi(const std::string& str)
{
std::istringstream stream(str);
int ret = 0;
stream >> ret;
return ret;
}
I see that solutions are offered that use std::stringstream or std::istringstream.
This might be perfectly OK for single threaded applications but if an application has lots of threads and often calls atoi(const std::string& str) implemented in this way that will result in performance degradation.
Read this discussion for example: http://gcc.gnu.org/ml/gcc-bugs/2009-05/msg00798.html.
And see a backtrace of the constructor of std::istringstream:
#0 0x200000007eb77810:0 in pthread_mutex_unlock+0x10 ()
from /usr/lib/hpux32/libc.so.1
#1 0x200000007ef22590 in std::locale::locale (this=0x7fffeee8)
at gthr-default.h:704
#2 0x200000007ef29500 in std::ios_base::ios_base (this=<not available>)
at /tmp/gcc-4.3.1.tar.gz/gcc-4.3.1/libstdc++-v3/src/ios.cc:83
#3 0x200000007ee8cd70 in std::basic_istringstream<char,std::char_traits<char>,std::allocator<char> >::basic_istringstream (this=0x7fffee4c,
__str=#0x7fffee44, __mode=_S_in) at basic_ios.h:456
#4 0x4000f70:0 in main () at main.cpp:7
So every time you enter atoi() and create a local varibale of type std::stringstream you will lock a global mutex and in a multithreaded application it is likely to result in waiting on this mutex.
So, it's better in a multithreaded application not to use std::stringstream. For example simply call atoi(const char*):
inline int atoi(const std::string& str)
{
return atoi(str.c_str());
}
For your example, you've got two options:
std::string mystring("4");
int myint = atoi(mystring.c_str());
Or something like:
std::string mystring("4");
std::istringstream buffer(mystring);
int myint = 0;
buffer >> myint;
The second option gives you better error management than the first.
You can write a more generic string to number convert as such:
template <class T>
T strToNum(const std::string &inputString,
std::ios_base &(*f)(std::ios_base&) = std::dec)
{
T t;
std::istringstream stringStream(inputString);
if ((stringStream >> f >> t).fail())
{
throw runtime_error("Invalid conversion");
}
return t;
}
// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue = strToNum<int>(strValue);
int intValueFromHex = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);
For conversions I find simplest to use boost's lexical_cast (except it might be too rigorously checking the validity of the conversions of string to other types).
It surely isn't very fast (it just uses std::stringstream under the hood, but significantly more convenient), but performance is often not needed where you convert values (e.g to create error output messages and such). (If you do lots of these conversions and need extreme performance, chances are you are doing something wrong and shouldn't be performing any conversions at all.)
Because the old C libraries still work with standard C++ types, with a very little bit of adaptation. You can easily change a const char * to a std::string with a constructor, and change back with std::string::c_str(). In your example, with std::string s, just call atoi(s.c_str()) and you're fine. As long as you can switch back and forth easily there's no need to add new functionality.
I'm not coming up with C functions that work on arrays and not container classes, except for things like qsort() and bsearch(), and the STL has better ways to do such things. If you had specific examples, I could consider them.
C++ does need to support the old C libraries for compatibility purposes, but the tendency is to provide new techniques where warranted, and provide interfaces for the old functions when there isn't much of an improvement. For example, the Boost lexical_cast is an improvement over such functions as atoi() and strtol(), much as the standard C++ string is an improvement over the C way of doing things. (Sometimes this is subjective. While C++ streams have considerable advantages over the C I/O functions, there's times when I'd rather drop back to the C way of doing things. Some parts of the C++ standard library are excellent, and some parts, well, aren't.)
There are all sorts of ways to parse a number from a string, atoi can easily be used with a std::string via atoi(std.c_str()) if you really want, but atoi has a bad interface because there is no sure way to determine if an error occurred during parsing.
Here's one slightly more modern C++ way to get an int from a std::string:
std::istringstream tmpstream(str);
if (tmpstream >> intvar)
{
// ... success! ...
}
The tongue in cheek answer is: Because STL is a half-hearted attempt to show how powerful C++ templates could be. Before they got to each corner of the problem space, time was up.
There are two reasons: Creating an API takes time and effort. Create a good API takes a lot of time and a huge effort. Creating a great API takes an insane amount of time and an incredible effort. When the STL was created, OO was still pretty new to the C++ people. They didn't have the ideas how to make fluent and simple API. Today, we think iterators are so 1990 but at the time, people thought "Bloody hell, why would I need that? for (int i=0; i<...) has been good enough for three decades!"
So STL didn't became the great, fluent API. This isn't all C++ fault because you can make good APIs with C++. But it was the first attempt to do that and it shows. Before the API could mature, it was turned into a standard and all the ugly shortcomings were set into stone. And on top of this, there was all this legacy code and all the libraries which already could do everything, so the pressure wasn't really there.
To solve your misery, give up on STL and have a look at the successors: Try boost and maybe Qt. Yeah, Qt is a UI library but it also has a pretty good standard library.
Since C++11, you can use std::stoi. It is like atoi but for std::string.