I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

Compare length of two strings

From Rosetta Code
Task
Compare length of two strings
You are encouraged to solve this task according to the task description, using any language you may know.

Basic Data Operation
This is a basic data operation. It represents a fundamental action on a basic data type.

You may see other such operations in the Basic Data Operations category, or:

Integer Operations
Arithmetic | Comparison

Boolean Operations
Bitwise | Logical

String Operations
Concatenation | Interpolation | Comparison | Matching

Memory Operations
Pointers & references | Addresses

Task

Given two strings of different length, determine which string is longer or shorter. Print both strings and their length, one on each line. Print the longer one first.

Measure the length of your string in terms of bytes or characters, as appropriate for your language. If your language doesn't have an operator for measuring the length of a string, note it.

Extra credit

Given more than two strings:
list = ["abcd","123456789","abcdef","1234567"]
Show the strings in descending length order.

Other tasks related to string operations:
Metrics
Counting
Remove/replace
Anagrams/Derangements/shuffling
Find/Search/Determine
Formatting
Song lyrics/poems/Mad Libs/phrases
Tokenize
Sequences



ALGOL 68[edit]

Algol 68 does not have an in-built "LENGTH" operator, it does have operators LWB and UPB which return the lower bound and upper bound of an array and as strings are arrays of characters, LENGTH can easily be constructed from these.
In most Algol 68 implementations such as Algol 68G and Rutgers Algol 68, the CHAR type is an 8-bit byte.

BEGIN # compare string lengths #
# returns the length of s using the builtin UPB and LWB operators #
OP LENGTH = ( STRING s )INT: ( UPB s + 1 ) - LWB s;
# prints s and its length #
PROC print string = ( STRING s )VOID:
print( ( """", s, """ has length: ", whole( LENGTH s, 0 ), " bytes.", newline ) );
STRING shorter = "short";
STRING not shorter = "longer";
IF LENGTH shorter > LENGTH not shorter THEN print string( shorter ) FI;
print string( not shorter );
IF LENGTH shorter <= LENGTH not shorter THEN print string( shorter ) FI
END
Output:
"longer" has length: 6 bytes.
"short" has length: 5 bytes.

C[edit]

Works with: C11
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int cmp(const int* a, const int* b)
{
return *b - *a; // reverse sort!
}
 
void compareAndReportStringsLength(const char* strings[], const int n)
{
if (n > 0)
{
char* has_length = "has length";
char* predicate_max = "and is the longest string";
char* predicate_min = "and is the shortest string";
char* predicate_ave = "and is neither the longest nor the shortest string";
 
int* si = malloc(2 * n * sizeof(int));
if (si != NULL)
{
for (int i = 0; i < n; i++)
{
si[2 * i] = strlen(strings[i]);
si[2 * i + 1] = i;
}
qsort(si, n, 2 * sizeof(int), cmp);
 
int max = si[0];
int min = si[2 * (n - 1)];
 
for (int i = 0; i < n; i++)
{
int length = si[2 * i];
char* string = strings[si[2 * i + 1]];
char* predicate;
if (length == max)
predicate = predicate_max;
else if (length == min)
predicate = predicate_min;
else
predicate = predicate_ave;
printf("\"%s\" %s %d %s\n",
string, has_length, length, predicate);
}
 
free(si);
}
else
{
fputs("unable allocate memory buffer", stderr);
}
}
}
 
int main(int argc, char* argv[])
{
char* list[] = { "abcd", "123456789", "abcdef", "1234567" };
 
compareAndReportStringsLength(list, 4);
 
return EXIT_SUCCESS;
}
Output:
"123456789" has length 9 and is the longest string
"1234567" has length 7 and is neither the longest nor the shortest string
"abcdef" has length 6 and is neither the longest nor the shortest string
"abcd" has length 4 and is the shortest string

C++[edit]

#include <iostream>
#include <algorithm>
#include <string>
#include <list>
 
using namespace std;
 
bool cmp(const string& a, const string& b)
{
return b.length() < a.length(); // reverse sort!
}
 
void compareAndReportStringsLength(list<string> listOfStrings)
{
if (!listOfStrings.empty())
{
char Q = '"';
string has_length(" has length ");
string predicate_max(" and is the longest string");
string predicate_min(" and is the shortest string");
string predicate_ave(" and is neither the longest nor the shortest string");
 
list<string> ls(listOfStrings); // clone to avoid side-effects
ls.sort(cmp);
int max = ls.front().length();
int min = ls.back().length();
 
for (list<string>::iterator s = ls.begin(); s != ls.end(); s++)
{
int length = s->length();
string* predicate;
if (length == max)
predicate = &predicate_max;
else if (length == min)
predicate = &predicate_min;
else
predicate = &predicate_ave;
 
cout << Q << *s << Q << has_length << length << *predicate << endl;
}
}
}
 
int main(int argc, char* argv[])
{
list<string> listOfStrings{ "abcd", "123456789", "abcdef", "1234567" };
compareAndReportStringsLength(listOfStrings);
 
return EXIT_SUCCESS;
}
Output:
"123456789" has length 9 and is the longest string
"1234567" has length 7 and is neither the longest nor the shortest string
"abcdef" has length 6 and is neither the longest nor the shortest string
"abcd" has length 4 and is the shortest string

C#[edit]

using System;
using System.Collections.Generic;
 
namespace example
{
class Program
{
static void Main(string[] args)
{
var strings = new string[] { "abcd", "123456789", "abcdef", "1234567" };
compareAndReportStringsLength(strings);
}
 
private static void compareAndReportStringsLength(string[] strings)
{
if (strings.Length > 0)
{
char Q = '"';
string hasLength = " has length ";
string predicateMax = " and is the longest string";
string predicateMin = " and is the shortest string";
string predicateAve = " and is neither the longest nor the shortest string";
string predicate;
 
(int, int)[] li = new (int, int)[strings.Length];
for (int i = 0; i < strings.Length; i++)
li[i] = (strings[i].Length, i);
Array.Sort(li, ((int, int) a, (int, int) b) => b.Item1 - a.Item1);
int maxLength = li[0].Item1;
int minLength = li[strings.Length - 1].Item1;
 
for (int i = 0; i < strings.Length; i++)
{
int length = li[i].Item1;
string str = strings[li[i].Item2];
if (length == maxLength)
predicate = predicateMax;
else if (length == minLength)
predicate = predicateMin;
else
predicate = predicateAve;
Console.WriteLine(Q + str + Q + hasLength + length + predicate);
}
}
}
 
}
}
 
Output:
"123456789" has length 9 and is the longest string
"1234567" has length 7 and is neither the longest nor the shortest string
"abcdef" has length 6 and is neither the longest nor the shortest string
"abcd" has length 4 and is the shortest string

FreeBASIC[edit]

sub comp( A as string, B as string )
if len(A)>=len(B) then
print A, len(A)
print B, len(B)
else
print B, len(B)
print A, len(A)
end if
end sub
 
comp( "abcd", "123456789" )
Output:
123456789      9
abcd           4

Haskell[edit]

Using native String type:

task s1 s2 = do
let strs = if length s1 > length s2 then [s1, s2] else [s2, s1]
mapM_ (\s -> putStrLn $ show (length s) ++ "\t" ++ show s) strs
λ> task "short string" "longer string"
13	"longer string"
12	"short string"

λ> Data.List.sortOn length ["abcd","123456789","abcdef","1234567"]
["abcd","abcdef","1234567","123456789"]

Data.List.sortOn (negate . length) ["abcd","123456789","abcdef","1234567"]
["123456789","1234567","abcdef","abcd"]

or more practically useful Text:

import qualified Data.Text as T
 
taskT s1 s2 = do
let strs = if T.length s1 > T.length s2 then [s1, s2] else [s2, s1]
mapM_ (\s -> putStrLn $ show (T.length s) ++ "\t" ++ show s) strs
λ> :set -XOverloadedStrings
λ> taskT "short string" "longer string"
13	"longer string"
12	"short string"

Java[edit]

Works with: Java version 11
Works with: Java version 17
package stringlensort;
 
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Comparator;
 
public class ReportStringLengths {
 
public static void main(String[] args) {
String[] list = {"abcd", "123456789", "abcdef", "1234567"};
String[] strings = args.length > 0 ? args : list;
 
compareAndReportStringsLength(strings);
}
 
/**
* Compare and report strings length to System.out.
*
* @param strings an array of strings
*/

public static void compareAndReportStringsLength(String[] strings) {
compareAndReportStringsLength(strings, System.out);
}
 
/**
* Compare and report strings length.
*
* @param strings an array of strings
* @param stream the output stream to write results
*/

public static void compareAndReportStringsLength(String[] strings, PrintStream stream) {
if (strings.length > 0) {
strings = strings.clone();
final String QUOTE = "\"";
Arrays.sort(strings, Comparator.comparing(String::length));
int min = strings[0].length();
int max = strings[strings.length - 1].length();
for (int i = strings.length - 1; i >= 0; i--) {
int length = strings[i].length();
String predicate;
if (length == max) {
predicate = "is the longest string";
} else if (length == min) {
predicate = "is the shortest string";
} else {
predicate = "is neither the longest nor the shortest string";
}
//@todo: StringBuilder may be faster
stream.println(QUOTE + strings[i] + QUOTE + " has length " + length
+ " and " + predicate);
}
}
}
}
Output:
"123456789" has length 9 and is the longest string
"1234567" has length 7 and is neither the longest nor the shortest string
"abcdef" has length 6 and is neither the longest nor the shortest string
"abcd" has length 4 and is the shortest string

Julia[edit]

Per the Julia docs, a String in Julia is a sequence of characters encoded as UTF-8. Most string methods in Julia actually accept an AbstractString, which is the supertype of strings in Julia regardless of the encoding, including the default UTF-8.

The Char data type in Julia is a 32-bit, potentially Unicode data type, so that if we enumerate a String as a Char array, we get a series of 32-bit characters:

s = "niño"
println("Position Char Bytes\n==============================")
for (i, c) in enumerate(s)
println("$i $c $(sizeof(c))")
end
 
Output:
Position  Char Bytes
==============================
1          n     4
2          i     4
3          ñ     4
4          o     4

However, if we index into the string, the index into the string will function as if the string was an ordinary C string, that is, an array of unsigned 8-bit integers. If the index attempts to index within a character of size greater than one byte, an error is thrown for bad indexing. This can be demonstrated by casting the above string to codeunits:

println("Position  Codeunit Bytes\n==============================")
for (i, c) in enumerate(codeunits(s))
println("$i $(string(c, base=16)) $(sizeof(c))")
end
 
Output:
Position  Codeunit Bytes
==============================
1            6e     1
2            69     1
3            c3     1
4            b1     1
5            6f     1

Note that the length of "niño" as a String is 4 characters, and the length of "niño" as codeunits (ie, 8 bit bytes) is 5. Indexing into the 4th position results in an error:

 
julia> s[4]
ERROR: StringIndexError: invalid index [4], valid nearby indices [3]=>'ñ', [5]=>'o'
 

So, whether a string is longer or shorter depends on the encoding, as below:

length("ñññ") < length("nnnn")  # true, and the usual meaning of length of a String
 
length(codeunits("ñññ")) > length(codeunits("nnnn")) # true as well
 

jq[edit]

Works with: jq

Works with gojq, the Go implementation of jq

 
def s1: "longer";
def s2: "shorter😀";
 
[s1,s2]
| sort_by(length)
| reverse[]
| "\"\(.)\" has length (codepoints) \(length) and utf8 byte length \(utf8bytelength)."
 
 
Output:
"shorter😀" has length (codepoints) 8 and utf8 byte length 11.
"longer" has length (codepoints) 6 and utf8 byte length 6.

Nim[edit]

In Nim, a character (char) is represented on a byte. A string is a sequence of characters with a length. For interoperability reason, an extra null is added at the end of the characters. A string is supposed to be encoded in UTF-8, but this is not enforced. The function len returns the length of the string i.e. its number of characters (without the extra null).

If we want to manage a string as a Unicode sequence of code points, we have to use the module unicode. We can convert a string in a sequence of runes, each rune being a unicode UTF-32 value. The length of this sequence is the number of code points.

import strformat, unicode
 
const
S1 = "marche"
S2 = "marché"
 
echo &"“{S2}”, byte length = {S2.len}, code points: {S2.toRunes.len}"
echo &"“{S1}”, byte length = {S1.len}, code points: {S1.toRunes.len}"
Output:
“marché”, byte length = 7, code points: 6
“marche”, byte length = 6, code points: 6

Pascal[edit]

Works with: Extended Pascal
program compareLengthOfStrings(output);
 
const
specimenA = 'RosettaCode';
specimenB = 'Pascal';
specimenC = 'Foobar';
specimenD = 'Pascalish';
 
type
specimen = (A, B, C, D);
specimens = set of specimen value [];
 
const
specimenMinimum = A;
specimenMaximum = D;
 
var
{ the explicit range min..max serves as a safeguard to update max const }
list: array[specimenMinimum..specimenMaximum] of string(24)
value [A: specimenA; B: specimenB; C: specimenC; D: specimenD];
lengthRelationship: array[specimen] of specimens;
 
procedure analyzeLengths;
var
left, right: specimen;
begin
for left := specimenMinimum to specimenMaximum do
begin
for right := specimenMinimum to specimenMaximum do
begin
if length(list[left]) < length(list[right]) then
begin
lengthRelationship[right] := lengthRelationship[right] + [right]
end
end
end
end;
 
procedure printSortedByLengths;
var
i: ord(specimenMinimum)..ord(specimenMaximum);
s: specimen;
begin
{ first the string longer than all other strings }
{ lastly print the string not longer than any other string }
for i := ord(specimenMaximum) downto ord(specimenMinimum) do
begin
{ for demonstration purposes: iterate over a set }
for s in [specimenMinimum..specimenMaximum] do
begin
{ card returns the cardinality ("population count") }
if card(lengthRelationship[s]) = i then
begin
writeLn(length(list[s]):8, ' ', list[s])
end
end
end
end;
 
begin
analyzeLengths;
printSortedByLengths
end.
Output:
      11 RosettaCode
       9 Pascalish
       6 Pascal
       6 Foobar

Perl[edit]

#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Compare_length_of_two_strings
use warnings;
 
for ( 'shorter thelonger', 'abcd 123456789 abcdef 1234567' )
{
print "\nfor strings => $_\n";
printf "length %d: %s\n", length(), $_
for sort { length $b <=> length $a } split;
}
Output:
for strings => shorter thelonger
length 9: thelonger
length 7: shorter

for strings => abcd 123456789 abcdef 1234567
length 9: 123456789
length 7: 1234567
length 6: abcdef
length 4: abcd

Phix[edit]

Lengths are in bytes, for codepoints use length(utf8_to_utf32()) or similar.

with javascript_semantics
sequence list = {"abcd","123456789","abcdef","1234567"},
         lens = apply(list,length),
         tags = reverse(custom_sort(lens,tagset(length(lens))))
papply(true,printf,{1,{"%s (length %d)\n"},columnize({extract(list,tags),extract(lens,tags)})})
Output:
123456789 (length 9)
1234567 (length 7)
abcdef (length 6)
abcd (length 4)

Python[edit]

Naive solution[edit]

Works with: Python version 3.8
A = 'I am string'
B = 'I am string too'
 
if len(A) > len(B):
print('"' + A + '"', 'has length', len(A), 'and is the longest of the two strings')
print('"' + B + '"', 'has length', len(B), 'and is the shortest of the two strings')
elif len(A) < len(B):
print('"' + B + '"', 'has length', len(B), 'and is the longest of the two strings')
print('"' + A + '"', 'has length', len(A), 'and is the shortest of the two strings')
else:
print('"' + A + '"', 'has length', len(A), 'and it is as long as the second string')
print('"' + B + '"', 'has length', len(B), 'and it is as long as the second string')
Output:
"I am string too" has length 15 and is the longest of the two strings
"I am string" has length 11 and is the shortest of the two strings

Advanced solution[edit]

Works with: Python version 3.8
"""
An example code for the task "Compare length of two strings" (Rosseta Code).
 
This example code can handle not only strings, but any objects.
"""

 
 
def _(message):
"""Translate: an placeholder for i18n and l10n gettext or similar."""
return message
 
 
def compare_and_report_length(*objects, sorted_=True, reverse=True):
"""
For objects given as parameters it prints which of them are the longest.
 
So if the parameters are strings, then the strings are printed, their
lengths and classification as the longest, shortest or average length.
 
Note that for N > 0 such objects (e.g., strings, bytes, lists) it is
possible that exactly M > 0 of them will be of the maximum length, K > 0 of
them will be of the minimum length. In particular, it is possible that all
objects will be exactly the same length. So we assume that if an object has
both the maximum and minimum length, it is referred to as a string with the
maximum length.
 
Args:
*objects (object): Any objects with defined length.
sorted_ (bool, optional): If sorted_ is False then objects are not
sorted. Defaults to True.
reverse (bool, optional): If reverse is True and sorted_ is True
objects are sorted in the descending order. If reverse is False
and sorted_ is True objects are sorted in the ascending order.
Defaults to True.
 
Returns:
None.
"""

lengths = list(map(len, objects))
max_length = max(lengths)
min_length = min(lengths)
lengths_and_objects = zip(lengths, objects)
 
# Longer phrases make translation into other natural languages easier.
#
has_length = _('has length')
if all(isinstance(obj, str) for obj in objects):
predicate_max = _('and is the longest string')
predicate_min = _('and is the shortest string')
predicate_ave = _('and is neither the longest nor the shortest string')
else:
predicate_max = _('and is the longest object')
predicate_min = _('and is the shortest object')
predicate_ave = _('and is neither the longest nor the shortest object')
 
if sorted_:
lengths_and_objects = sorted(lengths_and_objects, reverse=reverse)
 
for length, obj in lengths_and_objects:
if length == max_length:
predicate = predicate_max
elif length == min_length:
predicate = predicate_min
else:
predicate = predicate_ave
print(obj, has_length, length, predicate)
 
 
A = 'I am string'
B = 'I am string too'
LIST = ["abcd", "123456789", "abcdef", "1234567"]
 
 
print('Two strings')
print()
compare_and_report_length(A, B)
print()
 
print('A list of strings')
print()
compare_and_report_length(*LIST)
print()
 
Output:
Two strings

"I am string too" has length 15 and is the longest string
"I am string" has length 11 and is the shortest string

A list of strings

"123456789" has length 9 and is the longest string
"1234567" has length 7 and is neither the longest nor the shortest string
"abcdef" has length 6 and is neither the longest nor the shortest string
"abcd" has length 4 and is the shortest string

Raku[edit]

So... In what way does this task differ significantly from String length? Other than being horribly under specified?

In the modern world, string "length" is pretty much a useless measurement, especially in the absence of a specified encoding; hence Raku not even having an operator: "length" for strings.

say 'Strings (👨‍👩‍👧‍👦, 🤔🇺🇸, BOGUS!) sorted: "longest" first:';
say "$_: characters:{.chars}, Unicode code points:{.codes}, UTF-8 bytes:{.encode('UTF8').bytes}, UTF-16 bytes:{.encode('UTF16').bytes}" for <👨‍👩‍👧‍👦 BOGUS! 🤔🇺🇸>.sort: -*.chars;
Output:
Strings (👨‍👩‍👧‍👦, 🤔🇺🇸, BOGUS!) sorted: "longest" first:
BOGUS!: characters:6,  Unicode code points:6,  UTF-8 bytes:6,  UTF-16 bytes:12
🤔🇺🇸: characters:2,  Unicode code points:3,  UTF-8 bytes:12,  UTF-16 bytes:12
👨‍👩‍👧‍👦: characters:1,  Unicode code points:7,  UTF-8 bytes:25,  UTF-16 bytes:22

Ring[edit]

Two strings[edit]

 
see "working..." + nl
 
list = ["abcd","123456789"]
if len(list[1]) > len(list[2])
first = list[1]
second = list[2]
else
first = list[2]
second = list[1]
ok
 
see "Compare length of two strings:" + nl
see "" + first + " len = " + len(first) + nl + second + " len = " + len(second) + nl
see "done..." + nl
 
Output:
working...
Compare length of two strings:
123456789 len = 9
abcd len = 4
done...

More than two strings[edit]

 
see "working..." + nl
 
lenList = []
list = ["abcd","123456789","abcdef","1234567"]
for n = 1 to len(list)
len = len(list[n])
add(lenList,[len,n])
next
 
lenList = sort(lenList,1)
lenList = reverse(lenList)
 
see "Compare length of strings in descending order:" + nl
for n = 1 to len(lenList)
see "" + list[lenList[n][2]] + " len = " + lenList[n][1] + nl
next
see "done..." + nl
 
Output:
working...
Compare length of strings in descending order:
123456789 len = 9
1234567 len = 7
abcdef len = 6
abcd len = 4
done...

Wren[edit]

Library: Wren-upc

In Wren a string (i.e. an object of the String class) is an immutable sequence of bytes which is usually interpreted as UTF-8 but does not have to be.

With regard to string length, the String.count method returns the number of 'codepoints' in the string. If the string contains bytes which are invalid UTF-8, each such byte adds one to the count.

To find the number of bytes one can use String.bytes.count.

Unicode grapheme clusters, where what appears to be a single 'character' may in fact be an amalgam of several codepoints, are not directly supported by Wren but it is possible to measure the length in grapheme clusters of a string (i.e. the number of user perceived characters) using the Graphemes.clusterCount method of the Wren-upc module.

import "./upc" for Graphemes
 
var printCounts = Fn.new { |s1, s2, c1, c2|
var l1 = (c1 > c2) ? [s1, c1] : [s2, c2]
var l2 = (c1 > c2) ? [s2, c2] : [s1, c1]
System.print( "%(l1[0]) : length %(l1[1])")
System.print( "%(l2[0]) : length %(l2[1])\n")
}
 
var codepointCounts = Fn.new { |s1, s2|
var c1 = s1.count
var c2 = s2.count
System.print("Comparison by codepoints:")
printCounts.call(s1, s2, c1, c2)
}
 
var byteCounts = Fn.new { |s1, s2|
var c1 = s1.bytes.count
var c2 = s2.bytes.count
System.print("Comparison by bytes:")
printCounts.call(s1, s2, c1, c2)
}
 
var graphemeCounts = Fn.new { |s1, s2|
var c1 = Graphemes.clusterCount(s1)
var c2 = Graphemes.clusterCount(s2)
System.print("Comparison by grapheme clusters:")
printCounts.call(s1, s2, c1, c2)
}
 
for (pair in [ ["nino", "niño"], ["👨‍👩‍👧‍👦", "🤔🇺🇸"] ]) {
codepointCounts.call(pair[0], pair[1])
byteCounts.call(pair[0], pair[1])
graphemeCounts.call(pair[0], pair[1])
}
 
var list = ["abcd", "123456789", "abcdef", "1234567"]
System.write("Sorting in descending order by length in codepoints:\n%(list) -> ")
list.sort { |a, b| a.count > b.count }
System.print(list)
Output:
Comparison by codepoints:
niño : length 4
nino : length 4

Comparison by bytes:
niño : length 5
nino : length 4

Comparison by grapheme clusters:
niño : length 4
nino : length 4

Comparison by codepoints:
👨‍👩‍👧‍👦 : length 7
🤔🇺🇸 : length 3

Comparison by bytes:
👨‍👩‍👧‍👦 : length 25
🤔🇺🇸 : length 12

Comparison by grapheme clusters:
🤔🇺🇸 : length 2
👨‍👩‍👧‍👦 : length 1

Sorting in descending order by length in codepoints:
[abcd, 123456789, abcdef, 1234567] -> [123456789, 1234567, abcdef, abcd]

XPL0[edit]

string 0;               \use zero-terminated string convention
 
func StrLen(A); \Return number of characters in an ASCIIZ string
char A;
int I;
for I:= 0 to -1>>1 do
if A(I) = 0 then return I;
 
char List;
int M, N, SN, Len, Max;
[List:= ["abcd","123456789","abcdef","1234567"];
for M:= 0 to 3 do
[Max:= 0;
for N:= 0 to 3 do
[Len:= StrLen(@List(N,0));
if Len > Max then [Max:= Len; SN:= N];
];
Text(0, @List(SN,0));
Text(0, " length is "); IntOut(0, StrLen(@List(SN,0))); CrLf(0);
List(SN, 0):= 0; \truncate largest string
];
]
Output:
123456789 length is 9
1234567 length is 7
abcdef length is 6
abcd length is 4

Z80 Assembly[edit]

Terminator equ 0      ;null terminator
PrintChar equ &BB5A ;Amstrad CPC BIOS call, prints accumulator to screen as an ASCII character.
 
org &8000
 
ld hl,String1
ld de,String2
call CompareStringLengths
 
jp nc, Print_HL_First
ex de,hl
Print_HL_First:
push bc
push hl
call PrintString
pop hl
push hl
ld a,' '
call PrintChar
call getStringLength
ld a,b
call ShowHex_NoLeadingZeroes
call NewLine
pop hl
pop bc
 
ex de,hl
push bc
push hl
call PrintString
pop hl
push hl
ld a,' '
call PrintChar
call getStringLength
ld a,b
call ShowHex_NoLeadingZeroes
call NewLine
pop hl
pop bc
ReturnToBasic:
RET
 
String1:
byte "Hello",Terminator
String2:
byte "Goodbye",Terminator
 
;;;;;; RELEVANT SUBROUTINES - PRINTSTRING AND NEWLINE CREATED BY KEITH S. OF CHIBIAKUMAS
CompareStringLengths:
;HL = string 1
;DE = string 2
;CLOBBERS A,B,C
push hl
push de
ex de,hl
call GetStringLength
ld b,c
 
ex de,hl
call GetStringLength
ld a,b
cp c
pop de
pop hl
ret
;returns carry set if HL < DE, zero set if equal, zero & carry clear if HL >= DE
;returns len(DE) in C, and len(HL) in B.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetStringLength:
ld b,0
loop_getStringLength:
ld a,(hl)
cp Terminator
ret z
inc hl
inc b
jr loop_getStringLength
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NewLine:
push af
ld a,13 ;Carriage return
call PrintChar
ld a,10 ;Line Feed
call PrintChar
pop af
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintString:
ld a,(hl)
cp Terminator
ret z
inc hl
call PrintChar
jr PrintString
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ShowHex_NoLeadingZeroes:
;useful for printing values where leading zeroes don't make sense,
; such as money etc.
push af
and %11110000
ifdef gbz80 ;game boy
swap a
else ;zilog z80
rrca
rrca
rrca
rrca
endif
or a
call nz,PrintHexChar
;if top nibble of A is zero, don't print it.
pop af
and %00001111
or a
ret z ;if bottom nibble of A is zero, don't print it!
jp PrintHexChar
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintHexChar:
or a ;Clear Carry Flag
daa
add a,&F0
adc a,&40 ;This sequence converts a 4-bit hex digit to its ASCII equivalent.
jp PrintChar
Output:
Goodbye 7
Hello 5