Click here to Skip to main content
15,606,657 members
Articles / General Programming / String

Tagged as

Stats

13.4K views
58 downloads
5 bookmarked

StrToNum - A Header-only Library to Convert char and wchar_t Text Strings to Numbers

Rate me:
Please Sign up or sign in to vote.
4.08/5 (3 votes)
30 Jan 2023Apache1 min read
String to number conversion library, for char and wchar_t strings
This article discusses StrToNum which is a Header-only library to convert char and wchar_t Text strings to numbers.

Contents

Introduction

A header-only library to convert char and wchar_t text strings to numbers.

It is completely based on the Microsoft's std::from_chars implementation from the <charconv> standard header. The one significant difference though is that the ability to work with wchar_t type was added, because the C++ standard doesn't provide this functionality at the moment.

StrToNum features std::(w)string_view as an input, so you are no longer obliged to have only null-terminated strings, which is mandatory in all std::strto* functions family.

StrToNum also recognizes 0x and 0X prefixes as hex strings, when iBase is 0 or 16, which std::from_chars doesn't.

As a return type, StrToNum uses either std::optional (by default) or a newish and very convenient std::expected (through /std:c++latest), which either holds converted number or a from_chars_result struct, in case of converting error. Both these types are very similar.
To use the std::expected version, put the #define STN_USE_EXPECTED line before #include "StrToNum.h".

C++
template<typename IntegralT> requires std::is_integral_v<IntegralT>
[[nodiscard]] auto StrToNum(std::string_view sv, int iBase = 0)noexcept
->std::expected<IntegralT, from_chars_result<char>>
C++
template<typename IntegralT> requires std::is_integral_v<IntegralT>
[[nodiscard]] auto StrToNum(std::wstring_view wsv, int iBase = 0)noexcept
->std::expected<IntegralT, from_chars_result<wchar_t>>
C++
template<typename FloatingT> requires std::is_floating_point_v<FloatingT>
[[nodiscard]] auto StrToNum(std::string_view sv, 
  chars_format fmt = chars_format::general)noexcept
->std::expected<FloatingT, from_chars_result<char>>
C++
template<typename FloatingT> requires std::is_floating_point_v<FloatingT>
[[nodiscard]] auto StrToNum(std::wstring_view wsv, 
  chars_format fmt = chars_format::general)noexcept
->std::expected<FloatingT, from_chars_result<wchar_t>>

Basically, StrToNum is a thin wrapper over the std::from_chars machinery, with the convenient interface and the ability to work with wchar_t strings. Non-allocating, non-throwing, locale-independent.

Aliases

StrToNum is the main templated method which is very easy to use. But there are also predefined wrappers for convenience, for all integral and floating types:

C++
[[nodiscard]] inline constexpr auto StrToChar(std::string_view sv, int iBase = 0)noexcept
->std::expected<char, from_chars_result<char>>;
C++
[[nodiscard]] inline constexpr auto StrToUChar(std::string_view sv, int iBase = 0)noexcept
->std::expected<unsigned char, from_chars_result<char>>;
C++
[[nodiscard]] inline constexpr auto StrToShort(std::string_view sv, int iBase = 0)noexcept
->std::expected<short, from_chars_result<char>>;
C++
[[nodiscard]] inline constexpr auto StrToUShort(std::string_view sv, int iBase = 0)noexcept
->std::expected<unsigned short, from_chars_result<char>>;
C++
[[nodiscard]] inline constexpr auto StrToInt(std::string_view sv, int iBase = 0)noexcept
->std::expected<int, from_chars_result<char>>;
C++
[[nodiscard]] inline constexpr auto StrToUInt(std::string_view sv, int iBase = 0)noexcept
->std::expected<unsigned int, from_chars_result<char>>;
C++
[[nodiscard]] inline constexpr auto StrToLL(std::string_view sv, int iBase = 0)noexcept
->std::expected<long long, from_chars_result<char>>;
C++
[[nodiscard]] inline constexpr auto StrToULL(std::string_view sv, int iBase = 0)noexcept
->std::expected<unsigned long long, from_chars_result<char>>;
C++
[[nodiscard]] inline auto StrToFloat(std::string_view sv, 
chars_format fmt = chars_format::general)noexcept
->std::expected<float, from_chars_result<char>>;
C++
[[nodiscard]] inline auto StrToDouble
(std::string_view sv, chars_format fmt = chars_format::general)noexcept
->std::expected<double, from_chars_result<char>>;

Example

C++
#include <iomanip>
#include <iostream>
#include "StrToNum.h"

int main()
{
    constexpr const char* const str = "1234567890";
    constexpr const wchar_t* const wstr = L"1234567890";

    constexpr auto Int1 = stn::StrToInt(std::string_view(str).substr(0, 5));
    static_assert(Int1 == 12345);
    std::cout << "Int1 = " << Int1.value_or(-1) << "\n";

    constexpr auto Int2 = stn::StrToInt(std::wstring_view(wstr).substr(5));
    static_assert(Int2 == 67890);
    std::cout << "Int2 = " << Int2.value_or(-1) << "\n";

    constexpr auto LL1 = stn::StrToLL("0xABCDEF");
    static_assert(LL1 == 0xABCDEF);
    std::cout << std::hex << "LL1 = " << LL1.value_or(-1) << "\n";

    constexpr auto LL2 = stn::StrToLL(L"0xFEDCBA");
    static_assert(LL2 == 0xFEDCBA);
    std::cout << std::hex << "LL2 = " << LL2.value_or(-1) << "\n";

    const auto Dbl1 = stn::StrToDouble("3.1415926535");
    assert(Dbl1 == 3.1415926535);
    std::cout << std::fixed << std::setprecision(10) << "Dbl1 = " 
              << Dbl1.value_or(-1.) << "\n";

    const auto Dbl2 = stn::StrToDouble(L"-987.654");
    assert(Dbl2 == -987.654);
    std::cout << std::fixed << std::setprecision(3) << "Dbl2 = " 
              << Dbl2.value_or(-1.) << "\n";
    
    const auto flHex = stn::StrToFloat(L"0x1.Fp-2", stn::chars_format::hex);
    assert(flHex == 0x1.Fp-2);
    std::cout << std::fixed << std::setprecision(6) 
    << "flHex = " << flHex.value_or(-1.) << "\n";
}
This article was originally posted at https://github.com/jovibor/StrToNum

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0


Written By
Zaire Zaire
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionatoi vs StrToNum Pin
jmaida3-Nov-22 17:59
jmaida3-Nov-22 17:59 
AnswerRe: atoi vs StrToNum Pin
Jovibor4-Nov-22 12:07
Jovibor4-Nov-22 12:07 
GeneralRe: atoi vs StrToNum Pin
jmaida4-Nov-22 12:19
jmaida4-Nov-22 12:19 
GeneralRe: atoi vs StrToNum Pin
Jovibor4-Nov-22 14:06
Jovibor4-Nov-22 14:06 
GeneralRe: atoi vs StrToNum Pin
jmaida4-Nov-22 15:33
jmaida4-Nov-22 15:33 
SuggestionCrippled example Pin
E. Papulovskiy19-Jun-22 21:05
E. Papulovskiy19-Jun-22 21:05 
GeneralRe: Crippled example Pin
Jovibor19-Jun-22 22:02
Jovibor19-Jun-22 22:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.