Greetings everyone,
I was wondering if anyone can give me suggestions about the pros and cons of using cout over printf. I have found that sometimes its easier to use one, while other times its easier to use the other.
Thanks,
Jeff
Greetings everyone,
I was wondering if anyone can give me suggestions about the pros and cons of using cout over printf. I have found that sometimes its easier to use one, while other times its easier to use the other.
Thanks,
Jeff
If you are programming in C++, you should use cout and friends - the main advantage is that you can use operator overloading to write out class objects, which allow you to extend the types that are supported by C++ - something printf absolutely can't do. If you are programming in C, then printf is the only reasonable option.
I'm not aware of anything you can't do with cout (but yes, it's sometimes a bit more difficult to get perfect formatting, compared to printf).
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Don't use '*printf*', '*scanf*', and the like.
If you find the C++ stream manipulators difficult use 'Boost::Format' or similar.
Or if you want a truly type-safe alternative, search "CodeProject" and the like. I'm sure it is out there somewhere. ('Boost::Format' is type-safe after a fashion, but the format specifier is ignored in such cases of misuse.)
*shrug*
Or just write it yourself.
Soma
>extend the types that are supported by C++ - something printf absolutely can't do
Technically it's possible if you realize that printf is a glorified to_string function. If you provide that to_string operation in your class, you can use printf's string specifier. That's not much different from overloading the << operator.
My best code is written with the delete key.
Ok so what if I do this?
Code:#include <string> #include <cstdio> class MyClass { public: MyClass() : s("") { } virtual ~MyClass() { } void set(const char *s) { this->s = s; } const char *get(void) const { return this->s.c_str(); } operator char *() { return s.c_str(); } operator const char *() const { return s.c_str(); } private: std::string s; }; int main(void) { MyClass whatever; whatever.set("Hello world!"); printf("What you say? %s\n", (char *)whatever); return 0; }
Ok, so the word "absolutely" is perhaps not quite right - but it's clearly not actually extending printf() to cope with a new type, but rather creating a function that produces a string from the new type, and print it using %s, right?
Of course, if we introduce a "to_string" in each class, it's REALLY EASY to make a operator<< using the to_string function.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Of course, that will print the string value from the char* operator(), but it's still not MODIFYING printf to take the new type - you are just returning a string from the operator. And I fail to see how that is of any benefit over using operator<< (which can of course, like I pointed out in Prelude's example) use the char* operator() if you like.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Are the cast operators able to produce lvalues?
I want to do something like this
And half it set a member of object too 5. I guess maybe I should stick to regular eecwals sine operators huh?Code:(int)object = 5;
Even versions of '*printf*' that provide extensions to support user defined types on compilers that implement parsing to match types from the format string suffer from mechanical and semantic problems that are trivially solved with C++.
Soma
but dood, if u want to do printf("%*.3s", x, s) it is not as e-z.
Are you talking about operator overloading. Something like this?
Code:#include <iostream> #include <string> class COverLoaded { public: COverLoaded() : mNumericValue(0) { } public: COverLoaded &operator=(const int value) { this->mNumericValue = value; return *this; } COverLoaded &operator=(const std::string stringValue) { this->mStringValue = stringValue; return *this; } public: const int GetNumericValue() const { return this->mNumericValue; } const std::string &GetStringValue() const { return this->mStringValue; } private: int mNumericValue; std::string mStringValue; }; int main() { COverLoaded overloadedClass; // //Assign the values of the class(Note: I am using = for both a string and an int) // overloadedClass = 50; overloadedClass = "Some string value"; // //Output the internal values of the class // std::cout<<"Numeric Value = "<<overloadedClass.GetNumericValue()<<std::endl; std::cout<<"String Value = "<<overloadedClass.GetStringValue()<<std::endl; std::cin.get(); return 0; }
Woop?
Yeah, nvm what I was asking. I don't know why I wanted an lvalue. It doesn't even make sense.
The stream insertion operator makes things convenient and extensible, but I think it's hard to dispute the compactness and clarity of printf-style format specifiers, even if they aren't type-safe. If you want to use printf-style formatting, I'd suggest however that you use sprintf() to print into character arrays and then send the output through iostreams. Don't call printf() directly. The two libraries don't really play nice in terms of buffering or terminal settings.
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}