How to quickly concatenate char arrays? - c++

I'm implementing errors in my class. I mean I'm creating error messages for various misuses that might happen. I know how to combine strings and numbers though std::string or stringstream but I'm wondering if there is a shorter way to do it, heres an example from within the bracket operator:
std::stringstream err;
err << "The key " << key << " is not set.";
throw std::invalid_argument(err.str());
And I'm looking for something that would fit on one line sorta like this:
throw std::invalid_argument("The key " + key + " is not set."); <- obviously broken
Any format that the std::invalid_argument will take is fine.

Simply use std::to_string C++11
throw std::invalid_argument("The key " +
std::to_string( key ) +
" is not set.");

An alternative solution is to create your own exception class with a constructor that takes a uint64_t and creates the error message by itself:
#include <sstream>
#include <stdexcept>
#include <exception>
#include <string>
#include <iostream>
class MyException : public std::invalid_argument
{
private:
static std::string GetMessage(uint64_t key)
{
std::ostringstream err;
err << "The key " << key << " is not set.";
return err.str();
}
public:
MyException(uint64_t key) :
std::invalid_argument(GetMessage(key).c_str()) {}
virtual ~MyException() throw() {}
};
int main()
{
try
{
throw MyException(123);
}
catch (std::exception const &exc)
{
std::cout << exc.what() << "\n";
}
}

Related

Exception handling with stoi function

I have a little problem with exception handling in c++. I need to convert a number to string and if this string contains letters or more than 10 characters I need to give error. Here is the exception-handling part;
while ( cin >> input )
{
try
{
convert = castInput( input );
cout << "The number entered was: " << convert;
}
catch ( NonNumber &excp )
{
cout << "INVALID INPUT: " << excp.what();
}
catch ( Overflow &excp )
{
cout << "INVALID INPUT: " << excp.what();
}
cout << "\n\nPlease enter a number (end-of-file to terminate): ";
}
I used stoi function to converting the string to int but I think I need open 2 classes. I don't know why and how becase stoi fucntion own what function already.
I personally find that a regex is no overkill for this. Checking user input with a regex will have no negative impact on performance whatsoever.
But I think that you are more interested in exception handling. You need to read many many pages of a good C++ book to understand exception handling and its use cases.
And maybe, but I do not know, you want simply to catch the standard exceptions thrown by std::stoi. These are:
std::invalid_argument
std::out_of_range
That would be easy with writing
// Standard exceptions for stoi
catch (const std::invalid_argument & e) {
std::cout << e.what() << "\n";
}
catch (const std::out_of_range & e) {
std::cout << e.what() << "\n";
}
But maybe you want to learn, how to write own exceptions. For your specific requirements. But please note that your specification, e.g. "more than 10 digits" and "no letter" are maybe not quite what you want. With a machine, where int is 32bit bit, the maximum number that can be converted is: 2147483647. Any number bigger and still having only 10 characters, will throw a std::out_of_range. On the other hand numbers like 123X would be converted by std::stoi to 123. So, maybe your requirements are not so clear.
Anyway, to show you, how you could use own exceptions, I create 2 customized exceptions classes. And to make life easy, I derived those from std::exception (recommended).
See the below example:
#include <iostream>
#include <string>
#include <algorithm>
#include <exception>
#include <cctype>
#include <vector>
#include <sstream>
class StoiException : public std::exception
{
public:
StoiException(const std::string& msg) : message(msg) {}
virtual const char* what() const noexcept override { return message.c_str(); }
protected:
void setMessage(const std::string& msg) { message = msg; }
protected:
std::string message{};
};
class NoNumber : StoiException
{
public:
NoNumber(const std::string& msg) : StoiException(msg) { setMessage(std::string("My Exception -> NoNumber: ") + msg); }
virtual const char* what() const noexcept override { return message.c_str(); }
};
class Overflow : StoiException
{
public:
Overflow(const std::string& msg) : StoiException(msg) { setMessage(std::string("My Exception -> Overflow: ") + msg); }
virtual const char* what() const noexcept override { return message.c_str(); }
};
int castInput(std::string& input) {
int result{};
// Check, if there is any letter in the input string
if (std::any_of(input.begin(), input.end(), isalpha)) {
// If so, than throw
throw NoNumber(input);
}
// Check, if string has more than 10 characters
if (input.length() > 10) {
// If so, than throw
throw Overflow(input);
}
result = std::stoi(input);
return result;
}
std::istringstream testCin{ R"(123
567
2147483647
2147483648
123X
12345678901
xyzxyzxyzxyzxyz
)" };
int main() {
std::string input{};
// Read all input
while (testCin >> input) {
try {
// Convert
int convert = castInput(input);
// This will only be shown , if there is no exception
std::cout << "\nConverted Number is: " << convert << "\n";
}
// Catch all exceptions
catch (const NoNumber & e) {
std::cout << e.what() << "\n";
}
catch (const Overflow & e) {
std::cout << e.what() << "\n";
}
// Standard exceptions for stoi
catch (const std::invalid_argument & e) {
std::cout << e.what() << "\n";
}
catch (const std::out_of_range & e) {
std::cout << e.what() << "\n";
}
}
return 0;
}
Of course you can handle the std::stoi's exception also in your custom converter function. Then only your owwn exceptions are visible.
Please see:
#include <iostream>
#include <string>
#include <algorithm>
#include <exception>
#include <cctype>
#include <vector>
#include <sstream>
class StoiException : public std::exception
{
public:
StoiException(const std::string& msg) : message(msg) {}
virtual const char* what() const noexcept override { return message.c_str(); }
protected:
void setMessage(const std::string& msg) { message = msg; }
protected:
std::string message{};
};
class NoNumber : StoiException
{
public:
NoNumber(const std::string& msg) : StoiException(msg) { setMessage(std::string("My Exception -> NoNumber: ") + msg); }
virtual const char* what() const noexcept override { return message.c_str(); }
};
class Overflow : StoiException
{
public:
Overflow(const std::string& msg) : StoiException(msg) { setMessage(std::string("My Exception -> Overflow: ") + msg); }
virtual const char* what() const noexcept override { return message.c_str(); }
};
int castInput(std::string& input) {
int result{};
// Check, if there is any letter in the input string
if (std::any_of(input.begin(), input.end(), isalpha)) {
// If so, than throw
throw NoNumber(input);
}
// Check, if string has more than 10 characters
if (input.length() > 10) {
// If so, than throw
throw Overflow(input);
}
try {
result = std::stoi(input);
}
// Standard exceptions for stoi
catch (const std::invalid_argument & e) {
throw NoNumber(input);
}
catch (const std::out_of_range & e) {
throw Overflow(input);
}
return result;
}
std::istringstream testCin{ R"(123
567
2147483647
2147483648
123X
12345678901
xyzxyzxyzxyzxyz
)" };
int main() {
std::string input{};
// Read all input
while (testCin >> input) {
try {
// Convert
int convert = castInput(input);
// This will only be shown , if there is no exception
std::cout << "\nConverted Number is: " << convert << "\n";
}
// Catch all exceptions
catch (const NoNumber & e) {
std::cout << e.what() << "\n";
}
catch (const Overflow & e) {
std::cout << e.what() << "\n";
}
}
return 0;
}
But maybe, what you really want to have, is a function, that encapsulates std::stoi and has an additional return value to show, if it worked or not.
Please note: The last solution will also convert "123X" to 123. That is the difference to the previous versions.
#include <iostream>
#include <string>
#include <algorithm>
#include <exception>
#include <cctype>
#include <vector>
#include <sstream>
std::pair<bool, int> castInput(std::string& input) {
bool ok{ false };
int result{};
try {
result = std::stoi(input);
ok = true;
}
// Catch stoi errors
catch (const std::invalid_argument & e) {}
catch (const std::out_of_range & e) {}
return {ok, result};
}
std::istringstream testCin{ R"(123
567
2147483647
2147483648
123X
12345678901
xyzxyzxyzxyzxyz
)" };
int main() {
std::string input{};
// Read all input
while (testCin >> input) {
const auto [ok, convert] = castInput(input);
if (ok)
std::cout << "Converted value: " << convert << "\n";
else
std::cout << "String '" << input << "' could not be converted\n";
}
return 0;
}
Why not use Regex ? You just create a regex that check if there is letters or more than 10 chars, depending on the return you process the conversion or throw an custom exception.
This may be the regex you are looking for: ^[0-9]{1,10}$
std::regex reg("^[0-9]{1,10}$");
if (std::regex_match(string, reg))
// Do what you want (process convert)
Here is the regex cpp reference : here
Edit: As commented, regex is overkill for this, so you could simply make some basic checks inside you castInput function and throw NonNumber if you find a character in the string, or throw Overflow if string.len > 10.

C++ << no operator found

string toString() {
std::stringstream punkte;
std::stringstream name;
std::cout << name << "hat" << punkte << "Punkte" << '\n'
return 0;
}
At this line of code. I'm receiving the error C++ << no operator found
I can't figure out what my mistake is. I have read and tried different solutions. But nothing works. Can somebody please help?
std::cout << name << "hat" << punkte << "Punkte" << '\n';
I also included this in my code:
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream, std::stringbuf
#include <fstream>
There is no overload of operator<<() that will format a std::stringstream to a std::ostream. There error does not lie.
You are trying to call operator "<<" with a stringstream parameter. In other words:
std::cout << name;
Is equivalent to:
std::cout.operator<<(name);
And that operator<<(const std::stringstream&) function doesn't exists.
I think that what you want to do is assign each stringstream their values and then print both, isn't?
string toString()
{
std::stringstream punkte;
std::stringstream name;
name << "hat";
punkte << "Punkte";
std::cout << name.str() << punkte.str() << std::endl;
return name.str();
}
Be careful with your return value, and remember that a std::stringstream is not a std::string. If you want to retrieve the std:string in the stream, you must call the str() method.

Converting std::string to uint32_t

I have a string like below:
std::string strl="ffffffffffffffffffffffffffffffffffffffffffff";
I want to convert it into uint32_t variable like below:
uint32_t val = std::stoul(strl, nullptr, 16);
The above operation gives a "SIGABRT" signal and gives error:
terminate called after throwing an instance of 'std::out_of_range'
what(): stoul.
What changes to be done for resolving the issue or it is not possible with uint32_t datatype to store the string.
uint32_t can only store up to 0xffffffff as it's a 32 bit unsigned type, so it's not possible to store your string with that data type.
For the string you present, you'll need a big integer library to parse it.
Boost has a good one, and even includes typedefs like uint1024_t, so it's very simple to use.
See http://www.boost.org/doc/libs/1_58_0/libs/multiprecision/doc/html/index.html
If you really want to store the number in a uint32_t, you'll need to validate it.
I would approach it something like this:
#include <string>
#include <cstdint>
#include <stdexcept>
#include <iostream>
auto parse_hex_uint32(std::string const& input) -> std::uint32_t
try
{
std::size_t read_len = 0;
auto initial_result = std::stoull(input, &read_len, 16);
if (read_len != input.size())
{
throw std::runtime_error("invalid input: " + input);
}
if (initial_result > std::numeric_limits<std::uint32_t>::max())
{
throw std::out_of_range("number too large: " + std::to_string(initial_result));
}
return std::uint32_t(initial_result);
}
catch(...)
{
std::throw_with_nested(std::runtime_error("failed to parse " + input + " as hex uint32"));
}
void print_exception(const std::exception& e, int level = 0)
{
std::cerr << std::string(level, ' ') << "exception: " << e.what() << '\n';
try {
std::rethrow_if_nested(e);
} catch(const std::exception& e) {
print_exception(e, level+1);
} catch(...) {}
}
int main()
{
using namespace std::literals;
auto input = "ffffffffffffffff"s;
try
{
std::cout << parse_hex_uint32(input) << std::endl;
return 0;
}
catch(std::exception& e)
{
print_exception(e);
return 100;
}
}

Check if std::string is a valid uuid using boost

I want to check if a given string is a valid UUID using boost.
This is what I have come up with by looking at the documentation on the boost website:
void validate_uuid(const std::string& value)
{
try
{
boost::uuids::string_generator stringGenerator;
(void)stringGenerator(value);
}
catch (const std::exception& ex)
{
// ...
}
}
However, this does not always work.
If I call the function with a string that is too short for a valid UUID, an exception is thrown as expected. But if I call the function with an invalid UUID (e.g. 00000000-0000-0000-0000-00000000000K) no exception is thrown.
Please can someone clarify why this is happening.
Also, I've seen the use of boost::lexical_cast to read a string as a UUID as posted here. I'm wondering if I should follow that approach. Any advice appreciated.
The code you had does nothing in terms of validation. Instead it generates a UUID based on the constant passed (like a hash function).
Looking closer I was mistaken. The missing bit of validation appears to be a check on version:
Live On Coliru
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/string_generator.hpp>
#include <iostream>
bool is_valid_uuid(std::string const& maybe_uuid, boost::uuids::uuid& result) {
using namespace boost::uuids;
try {
result = string_generator()(maybe_uuid);
return result.version() != uuid::version_unknown;
} catch(...) {
return false;
}
}
int main() {
std::string maybe_uuid;
std::cout << "Enter a UUID: ";
while (std::cin >> maybe_uuid)
{
boost::uuids::uuid result;
bool is_valid = is_valid_uuid(maybe_uuid, result);
std::cout << "\n'" << maybe_uuid << "' valid: " << std::boolalpha << is_valid << "\n";
if (is_valid)
std::cout << "Parsed value: " << result << "\n";
}
}
Sample output from Coliru: echo 00000000-0000-{0,4}000-0000-000000000000 $(uuidgen) "{$(uuidgen)}" | ./a.out:
Enter a UUID:
'00000000-0000-0000-0000-000000000000' valid: false
'00000000-0000-4000-0000-000000000000' valid: true
Parsed value: 00000000-0000-4000-0000-000000000000
'a2c59f5c-6c9b-4800-afb8-282fc5e743cc' valid: true
Parsed value: a2c59f5c-6c9b-4800-afb8-282fc5e743cc
'{82a31d37-6fe4-4b80-b608-c63ec5ecd578}' valid: true
Parsed value: 82a31d37-6fe4-4b80-b608-c63ec5ecd578
This seems way easier:
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
#include <sstream>
int main()
{
std::string t1("01234567-89ab-cdef-0123-456789abcdef");
std::string t2("Test UUID");
boost::uuids::uuid u;
std::istringstream iss(t1);
iss >> u;
if (iss.good())
std::cerr << "'" << t1 << "' is a good UUID\n";
else
std::cerr << "'" << t1 << "' is not a good UUID\n";
iss.str(t2);
iss >> u;
if (iss.good())
std::cerr << "'" << t2 << "' is a good UUID\n";
else
std::cerr << "'" << t2 << "' is not a good UUID\n";
return 0;
}
$ g++ -I/usr/local/include -std=c++11 test1.cpp
$ a.out
'01234567-89ab-cdef-0123-456789abcdef' is a good UUID
'Test UUID' is not a good UUID
Since you already use boost you can use regex to check whether your string is a valid UUID
E.g for UUID version 4 you could use the following code
bool validate_uuid(const std::string& s)
{
static const boost::regex e("[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}");
return regex_match(s, e); // note: case sensitive now
}
(As mentioned in this answer and in the wiki there should be a valid version digit and another "special" digit).
Live on coliru.

How can I replace my c++ exception macro with an inline function with __LINE__ and __FILE__ support?

I currently read the book Effective C++ from Scott Meyers. It says I should prefer inline functions over #define for function-like macros.
Now I try to code an inline function to replace my exception macro. My old macro looks like this:
#define __EXCEPTION(aMessage) \
{ \
std::ostringstream stream; \
stream << "EXCEPTION: " << aMessage << ", file " <<__FILE__ << " line " << __LINE__; \
throw ExceptionImpl(stream.str()); \
}
My new inline function is this:
inline void __EXCEPTION(const std::string aMessage)
{
std::ostringstream stream;
stream << "EXCEPTION: " << aMessage << ", file " <<__FILE__ << " line " << __LINE__;
throw ExceptionImpl(stream.str());
}
As probably some people already expect, now the __FILE__ and __LINE__ macros are useless, because they refer always to the C++-file with the definition of the inline function.
Is there any way to circumvent this behaviour or should I stick with my old macro? I read this threads here, and I already suspect that there is probably no way of my second example to work fine:
Behavior of __LINE__ in inline functions
__FILE__, __LINE__, and __FUNCTION__ usage in C++
Don't use __ (double underscore) as it's reserved. Having an inline function is better.
However, here you need a mix of macro and the function, hence you can do following:
#define MY_EXCEPTION(aMessage) MyException(aMessage, __FILE__, __LINE__)
inline void MyException(const std::string aMessage,
const char* fileName,
const std::size_t lineNumber)
{
std::ostringstream stream;
stream << "EXCEPTION: " << aMessage << ", file " << fileName << " line " << lineNumber;
throw ExceptionImpl(stream.str());
}
I see this is an old question but I think that the approach of printing the line in the exception macro is fundamentally flawed and I think I have a better alternative. I assume that the macro is used similar to the following code:
try {
/// code
throw;
}
catch (...) { __EXCEPTION(aMessage); }
With this approach the macro prints the location where the exception was catch'ed. But for troubleshooting and debugging the location where it was throw'n is usually more useful.
To get that information, we can attach the __FILE__ and __LINE__ macros to the exception. However, we still can't get completely rid of macros, but we get at least the exact throw location:
#include <iostream>
#include <exception>
#include <string>
#define MY_THROW(msg) throw my_error(__FILE__, __LINE__, msg)
struct my_error : std::exception
{
my_error(const std::string & f, int l, const std::string & m)
: file(f)
, line(l)
, message(m)
{}
std::string file;
int line;
std::string message;
char const * what() const throw() { return message.c_str(); }
};
void my_exceptionhandler()
{
try {
throw; // re-throw the exception and capture the correct type
}
catch (my_error & e)
{
std::cout << "Exception: " << e.what() << " in line: " << e.line << std::endl;
}
}
int main()
{
try {
MY_THROW("error1");
} catch(...) { my_exceptionhandler(); }
}
There is one additional improvement possible if we are willing to use boost::exception: We can get rid of macro definitons at least in our own code. The whole program gets shorter and the locations of code execution and error handling can be nicely separated:
#include <iostream>
#include <boost/exception/all.hpp>
typedef boost::error_info<struct tag_error_msg, std::string> error_message;
struct error : virtual std::exception, virtual boost::exception { };
struct my_error: virtual error { };
void my_exceptionhandler()
{
using boost::get_error_info;
try {
throw;
}
catch(boost::exception & e)
{
char const * const * file = get_error_info<boost::throw_file>(e);
int const * line = get_error_info<boost::throw_line>(e);
char const * const * throw_func = get_error_info<boost::throw_function>(e);
std::cout << diagnostic_information(e, false)
<< " in File: " << *file << "(" << *line << ")"
" in Function: " << *throw_func;
}
}
int main()
{
try {
BOOST_THROW_EXCEPTION(my_error() << error_message("Test error"));
} catch(...) { my_exceptionhandler(); }
}
Please consider that there is another difference between using the #define function-like macro in your case in comparison to inline functions. You could have used streaming operators and parameters in your macro's invocation to be composed as your message's text:
__EXCEPTION( "My message with a value " << val )
But most times I've needed something like this, it was to check on a certain condition (like an assertion). So you could extend #iammilind's example with something like:
#define MY_EXCEPTION_COND( cond ) \
if (bool(cond) == false) \
{ \
std::string _s( #cond " == false" ); \
MyException(_s, __FILE__, __LINE__); \
}
Or something a little more specialized where the values are also printed:
template <typename T>
inline void MyExceptionValueCompare(const T& a,
const T& b,
const char* fileName,
const std::size_t lineNumber)
{
if (a != b)
{
std::ostringstream stream;
stream << "EXCEPTION: " << a << " != " << b << ", file " << fileName << " line " << lineNumber;
throw ExceptionImpl(stream.str());
}
}
#define MY_EXCEPTION_COMP( a, b ) MyExceptionValueCompare(a, b, __FILE__, __LINE__)
Another approach you may want to take a look at is Microsoft's usage of their __LineInfo class in the Microsoft::VisualStudio::CppUnitTestFramework namespace (VC\UnitTest\Include\CppUnitTestAssert.h). See https://msdn.microsoft.com/en-us/library/hh694604.aspx
With std::experimental::source_location, you might do:
#include <experimental/source_location>
void THROW_EX(const std::string_view& message,
const std::experimental::source_location& location
= std::experimental::source_location::current())
{
std::ostringstream stream;
stream << "EXCEPTION: " << message
<< ", file " << location.file_name()
<< " line " << location.line();
throw ExceptionImpl(stream.str());
}