diff --git a/doc/specs/stdlib_str2num.md b/doc/specs/stdlib_str2num.md index cf4b58949..3a2fcb36d 100644 --- a/doc/specs/stdlib_str2num.md +++ b/doc/specs/stdlib_str2num.md @@ -38,6 +38,40 @@ Return a scalar of numerical type (i.e., `integer`, or `real`). {!example/strings/example_string_to_number.f90!} ``` +## `to_num_base` - conversion of strings to numbers with status + +### Status + +Experimental + +### Description + +Convert the initial number in a string and return the position where +conversion stopped together with a status code. + +### Syntax + +`call ` [[stdlib_str2num(module):to_num_base(interface)]] `(string, number, position, status)` + +### Arguments + +`string`: argument has `intent(in)` and is of type `character(*)`. + +`number`: argument has `intent(out)` and is of numerical type (that is of +`integer` or of `real`). + +`position`: argument has `intent(out)` and is of type `integer(int8)`. It is +the position of the first character after the converted number. + +`status`: argument has `intent(out)` and is of type `integer(int8)`. A value of +zero indicates a successful conversion. + +### Example + +```fortran +{!example/strings/example_to_num_base.f90!} +``` + ## `to_num_from_stream` - conversion of a stream of values in a string to numbers ### Status diff --git a/example/strings/CMakeLists.txt b/example/strings/CMakeLists.txt index cdf4d778c..5a21c67a6 100644 --- a/example/strings/CMakeLists.txt +++ b/example/strings/CMakeLists.txt @@ -13,4 +13,5 @@ ADD_EXAMPLE(to_string) ADD_EXAMPLE(to_c_char) ADD_EXAMPLE(zfill) ADD_EXAMPLE(string_to_number) +ADD_EXAMPLE(to_num_base) ADD_EXAMPLE(stream_of_strings_to_numbers) diff --git a/example/strings/example_to_num_base.f90 b/example/strings/example_to_num_base.f90 new file mode 100644 index 000000000..158aadfef --- /dev/null +++ b/example/strings/example_to_num_base.f90 @@ -0,0 +1,13 @@ +program example_to_num_base + use stdlib_kinds, only: int8, int32 + use stdlib_str2num, only: to_num_base + implicit none + character(*), parameter :: text = " 123 rest" + integer(int32) :: value + integer(int8) :: position, status + + call to_num_base(text, value, position, status) + print *, "value:", value + print *, "next character:", text(position:position) + print *, "status:", status +end program example_to_num_base diff --git a/src/strings/stdlib_str2num.fypp b/src/strings/stdlib_str2num.fypp index ffb574821..c622aff74 100644 --- a/src/strings/stdlib_str2num.fypp +++ b/src/strings/stdlib_str2num.fypp @@ -38,7 +38,7 @@ module stdlib_str2num use, intrinsic:: ieee_arithmetic, only: ieee_value, ieee_positive_inf, ieee_quiet_nan implicit none private - public :: to_num, to_num_from_stream + public :: to_num, to_num_from_stream, to_num_base integer(int8), parameter :: digit_0 = ichar('0',int8) integer(int8), parameter :: period = ichar('.',int8) - digit_0 diff --git a/test/string/test_string_to_number.fypp b/test/string/test_string_to_number.fypp index 10675e164..39afe887a 100644 --- a/test/string/test_string_to_number.fypp +++ b/test/string/test_string_to_number.fypp @@ -1,7 +1,7 @@ #: include "common.fypp" module test_string_to_number use stdlib_kinds, only: sp, dp, xdp, qp, int8, int16, int32, int64 - use stdlib_str2num, only: to_num + use stdlib_str2num, only: to_num, to_num_base use testdrive, only : new_unittest, unittest_type, error_type, check implicit none @@ -14,7 +14,8 @@ contains testsuite = [ & new_unittest("to_sp", test_to_sp), & - new_unittest("to_dp", test_to_dp) & + new_unittest("to_dp", test_to_dp), & + new_unittest("to_num_base", test_to_num_base) & #:if WITH_QP , new_unittest("to_qp", test_to_qp) & #:endif @@ -215,7 +216,24 @@ contains end function end subroutine #:endfor - + + subroutine test_to_num_base(error) + type(error_type), allocatable, intent(out) :: error + integer(int32) :: value + integer(int8) :: position, status + + call to_num_base(" 123 rest", value, position, status) + call check(error, value == 123_int32) + if (allocated(error)) return + call check(error, position == 5_int8) + if (allocated(error)) return + call check(error, status == 0_int8) + if (allocated(error)) return + + call to_num_base("2147483648", value, position, status) + call check(error, status /= 0_int8) + end subroutine + end module test_string_to_number program tester