From 5a71e3b3c7fffe82d77087003ff45f68a3583240 Mon Sep 17 00:00:00 2001 From: ecasglez Date: Thu, 22 Dec 2022 21:09:01 +0100 Subject: [PATCH 1/2] New zfill function to left-pad a string with zeros --- doc/specs/stdlib_strings.md | 39 ++++++++++++++++++++ example/strings/CMakeLists.txt | 1 + example/strings/example_zfill.f90 | 15 ++++++++ src/stdlib_strings.fypp | 35 +++++++++++++++++- test/string/test_string_functions.f90 | 53 ++++++++++++++++++++++++++- 5 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 example/strings/example_zfill.f90 diff --git a/doc/specs/stdlib_strings.md b/doc/specs/stdlib_strings.md index cb2c18c59..78fe24240 100644 --- a/doc/specs/stdlib_strings.md +++ b/doc/specs/stdlib_strings.md @@ -421,6 +421,45 @@ The result is a scalar of integer type or an integer array of rank equal to the {!example/strings/example_count.f90!} ``` + + +### `zfill` + +#### Description + +Returns a string of length `output_length` left padded with zeros. +If `output_length` is less than or equal to the length of `string`, padding is not performed. + +#### Syntax + +`string = [[stdlib_strings(module):zfill(interface)]] (string, output_length)` + +#### Status + +Experimental + +#### Class + +Pure function + +#### Argument + +- `string`: Character scalar or [[stdlib_string_type(module):string_type(type)]]. + This argument is intent(in). +- `output_length`: integer. + This argument is intent(in). + +#### Result value + +The result is of the same type as `string`. + +#### Example + +```fortran +{!example/strings/example_zfill.f90!} +``` + + ### `to_string` diff --git a/example/strings/CMakeLists.txt b/example/strings/CMakeLists.txt index 6cc750765..086140bcb 100644 --- a/example/strings/CMakeLists.txt +++ b/example/strings/CMakeLists.txt @@ -9,3 +9,4 @@ ADD_EXAMPLE(slice) ADD_EXAMPLE(starts_with) ADD_EXAMPLE(strip) ADD_EXAMPLE(to_string) +ADD_EXAMPLE(zfill) diff --git a/example/strings/example_zfill.f90 b/example/strings/example_zfill.f90 new file mode 100644 index 000000000..fc44840a8 --- /dev/null +++ b/example/strings/example_zfill.f90 @@ -0,0 +1,15 @@ +program example_zfill + use stdlib_string_type, only: string_type, assignment(=), write (formatted) + use stdlib_strings, only: zfill + implicit none + type(string_type) :: string + + string = "left pad this string with zeros" +! string <-- "left pad this string with zeros" + + print '(dt)', zfill(string, 36) ! "00000left pad this string with zeros" + + string = zfill(string, 36) +! string <-- "00000left pad this string with zeros" + +end program example_zfill diff --git a/src/stdlib_strings.fypp b/src/stdlib_strings.fypp index 367c08159..a70bb38d2 100644 --- a/src/stdlib_strings.fypp +++ b/src/stdlib_strings.fypp @@ -14,7 +14,7 @@ module stdlib_strings public :: to_string public :: strip, chomp public :: starts_with, ends_with - public :: slice, find, replace_all, padl, padr, count + public :: slice, find, replace_all, padl, padr, count, zfill !> Version: experimental !> @@ -155,6 +155,15 @@ module stdlib_strings module procedure :: count_char_char end interface count + !> Version: experimental + !> + !> Left pad the input string with zeros. + !> [Specifications](../page/specs/stdlib_strings.html#zfill) + interface zfill + module procedure :: zfill_string + module procedure :: zfill_char + end interface zfill + contains @@ -909,6 +918,30 @@ contains end if end function count_char_char + + !> Left pad the input string with zeros + !> + !> Returns a new string + pure function zfill_string(string, output_length) result(res) + type(string_type), intent(in) :: string + integer, intent(in) :: output_length + type(string_type) :: res + + res = string_type(padl(char(string), output_length, "0")) + + end function zfill_string + + !> Left pad the input string with zeros + !> + !> Returns a new string + pure function zfill_char(string, output_length) result(res) + character(len=*), intent(in) :: string + integer, intent(in) :: output_length + character(len=max(len(string), output_length)) :: res + + res = padl(string, output_length, "0") + + end function zfill_char end module stdlib_strings diff --git a/test/string/test_string_functions.f90 b/test/string/test_string_functions.f90 index df00d1ab6..d62d87d3f 100644 --- a/test/string/test_string_functions.f90 +++ b/test/string/test_string_functions.f90 @@ -4,7 +4,7 @@ module test_string_functions use testdrive, only : new_unittest, unittest_type, error_type, check use stdlib_string_type, only : string_type, assignment(=), operator(==), & to_lower, to_upper, to_title, to_sentence, reverse - use stdlib_strings, only: slice, find, replace_all, padl, padr, count + use stdlib_strings, only: slice, find, replace_all, padl, padr, count, zfill use stdlib_optval, only: optval use stdlib_strings, only : to_string implicit none @@ -29,7 +29,8 @@ subroutine collect_string_functions(testsuite) new_unittest("replace_all", test_replace_all), & new_unittest("padl", test_padl), & new_unittest("padr", test_padr), & - new_unittest("count", test_count) & + new_unittest("count", test_count), & + new_unittest("zfill", test_zfill) & ] end subroutine collect_string_functions @@ -659,6 +660,54 @@ subroutine test_count(error) end subroutine test_count + subroutine test_zfill(error) + !> Error handling + type(error_type), allocatable, intent(out) :: error + + type(string_type) :: test_string + character(len=:), allocatable :: test_char + + test_string = "left pad this string" + test_char = " left pad this string " + + ! output_length > len(string) + call check(error, zfill(test_string, 25) == "00000left pad this string", & + & 'zfill: output_length > len(string), test_case 1') + if (allocated(error)) return + call check(error, zfill(test_string, 22) == "00left pad this string", & + & 'zfill: output_length > len(string), test_case 2') + if (allocated(error)) return + call check(error, zfill(test_string, 23) == "000left pad this string", & + & 'zfill: output_length > len(string), test_case 3') + if (allocated(error)) return + call check(error, zfill(test_char, 26) == "00 left pad this string ", & + & 'zfill: output_length > len(string), test_case 4') + if (allocated(error)) return + call check(error, zfill("", 10) == "0000000000", & + & 'zfill: output_length > len(string), test_case 5') + if (allocated(error)) return + + ! output_length <= len(string) + call check(error, zfill(test_string, 18) == "left pad this string", & + & 'zfill: output_length <= len(string), test_case 1') + if (allocated(error)) return + call check(error, zfill(test_string, -4) == "left pad this string", & + & 'zfill: output_length <= len(string), test_case 2') + if (allocated(error)) return + call check(error, zfill(test_char, 20) == " left pad this string ", & + & 'zfill: output_length <= len(string), test_case 3') + if (allocated(error)) return + call check(error, zfill(test_char, 17) == " left pad this string ", & + & 'zfill: output_length <= len(string), test_case 4') + if (allocated(error)) return + call check(error, zfill("", 0) == "", & + & 'zfill: output_length <= len(string), test_case 5') + if (allocated(error)) return + call check(error, zfill("", -12) == "", & + & 'zfill: output_length <= len(string), test_case 6') + + end subroutine test_zfill + end module test_string_functions From c283687284f138eeae25b9b83063c5e7149a9540 Mon Sep 17 00:00:00 2001 From: Milan Curcic Date: Fri, 3 Mar 2023 16:01:31 -0500 Subject: [PATCH 2/2] Minor edit --- doc/specs/stdlib_strings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/specs/stdlib_strings.md b/doc/specs/stdlib_strings.md index 78fe24240..f61ae3edf 100644 --- a/doc/specs/stdlib_strings.md +++ b/doc/specs/stdlib_strings.md @@ -427,7 +427,7 @@ The result is a scalar of integer type or an integer array of rank equal to the #### Description -Returns a string of length `output_length` left padded with zeros. +Returns a string of length `output_length` left-padded with zeros. If `output_length` is less than or equal to the length of `string`, padding is not performed. #### Syntax