#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cassert>
using namespace std;
template <size_t N>
constexpr char LastCharacter(char (&input)[N])
{
static_assert(N >= 1, "A character array representing a string must have atleast 1 character AND a null terminator.");
return (input[N - 1] == '\0') ? input[N - 2] : input[N - 1];
}
int main ()
{
auto print_c = [](char c)
{
if (c) std::cout << "'" << c << "'\n";
else std::cout << "'" << "\\0" << "'\n";
};
{
char str[] = {'h', 'e','l', 'l', 'o'};
for (auto c : str) print_c(c);
std::cout << R"(char str[] = {'h', 'e','l', 'l', 'o'})" << "\n";
std::cout << "str[N] last character " << LastCharacter(str) << "\n\n";
std::cout << "char str[N], N = " << std::size(str) << "\n\n";
}
{
char str[] = {'h', 'e','l', 'l', 'o', '\0'};
for (auto c : str) print_c(c);
std::cout << R"(char str[] = {'h', 'e','l', 'l', 'o', '\0'})" << "\n";
std::cout << "str[N] last character " << LastCharacter(str) << "\n\n";
std::cout << "char str[N], N = " << std::size(str) << "\n\n";
}
{
char str[] = "hello";
for (auto c : str) print_c(c);
std::cout << R"(char str[] = "hello")" << "\n";
std::cout << "str[N] last character " << LastCharacter(str) << "\n\n";
std::cout << "char str[N], N = " << std::size(str) << "\n\n";
}
{
char str[] = {'b','\0'};
for (auto c : str) print_c(c);
std::cout << R"(char str[] = {'\0'})" << "\n";
std::cout << "str[N] last character " << LastCharacter(str) << "\n\n";
std::cout << "char str[N], N = " << std::size(str) << "\n\n";
}
{
char str[] = "a";
for (auto c : str) print_c(c);
std::cout << R"(char str[] = "")" << "\n";
std::cout << "str[N] last character " << LastCharacter(str) << "\n\n";
std::cout << "char str[N], N = " << std::size(str) << "\n\n";
}
{
//
// This does not compile, this is one way to protect from empty strings.
// char str[] = {};
// for (auto c : str) print_c(c);
// std::cout << "char str[N], N = " << std::size(str) << "\n";
}
return 0;
}