Initial commit

This commit is contained in:
Leonetienne 2022-03-19 14:15:03 +01:00
commit 481eeccdc7
6 changed files with 357 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build/

9
CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.16)
project(wdate)
set(CMAKE_CXX_STANDARD 17)
add_executable(wdate
main.cpp
)

156
StringTools.cpp Normal file
View File

@ -0,0 +1,156 @@
#include "StringTools.h"
#include <sstream>
std::string StringTools::Replace(const std::string& str, const char find, const std::string& subst) {
std::stringstream ss;
for (std::size_t i = 0; i < str.length(); i++)
{
if (str[i] != find)
ss << str[i];
else
ss << subst;
}
return ss.str();
}
std::string StringTools::Replace(const std::string& str, const std::string& find, const std::string& subst) {
if (find.length() == 0)
return str;
std::stringstream ss;
std::size_t posFound = 0;
std::size_t lastFound = 0;
while (posFound != std::string::npos)
{
lastFound = posFound;
posFound = str.find(find, posFound);
if (posFound != std::string::npos)
{
ss << str.substr(lastFound, posFound - lastFound) << subst;
posFound += find.length();
}
else
{
ss << str.substr(lastFound, (str.length()) - lastFound);
}
}
return ss.str();
}
std::string StringTools::Replace(const std::string& str, const char find, const char subst) {
std::stringstream ss;
ss << subst;
return Replace(str, find, ss.str());
}
std::string StringTools::Replace(const std::string& str, const std::string& find, const char subst) {
std::stringstream ss;
ss << subst;
return Replace(str, find, ss.str());
}
std::string StringTools::Lower(const std::string& str) {
std::stringstream ss;
for (std::size_t i = 0; i < str.size(); i++)
{
const char c = str[i];
// Quick-accept: regular letters
if ((c >= 'A') && (c <= 'Z'))
ss << (char)(c | 32);
// Else: keep the character as is
else ss << c;
}
return ss.str();
}
std::string StringTools::Upper(const std::string& str) {
std::stringstream ss;
for (std::size_t i = 0; i < str.size(); i++)
{
const char c = str[i];
// Quick-accept: regular letters
if ((c >= 'a') && (c <= 'z'))
ss << (char)(c & ~32);
// Else: keep the character as is
else ss << c;
}
return ss.str();
}
std::vector<std::string> StringTools::Split(const std::string& str, const std::string& seperator) {
std::vector<std::string> toRet;
// Quick-accept: str length is 0
if (str.length() == 0)
toRet.push_back("");
// Quick-accept: seperator length is 0
else if (seperator.length() == 0) {
for (const char c : str)
toRet.push_back(std::string(&c, (&c) + 1));
}
else {
std::size_t idx = 0;
while (idx != std::string::npos) {
std::size_t lastIdx = idx;
idx = str.find(seperator, idx);
// Grab our substring until the next finding of sep
if (idx != std::string::npos) {
toRet.push_back(str.substr(
lastIdx,
idx - lastIdx
));
idx += seperator.length();
}
// No more seperator found. Grab the rest until the end of the string
else {
toRet.push_back(str.substr(
lastIdx
));
}
}
}
return toRet;
}
std::string StringTools::PadLeft(const std::string& str, const char pad, const std::size_t len) {
std::stringstream ss;
for (std::size_t i = str.length(); i < len; i++)
ss << pad;
ss << str;
return ss.str();
}
std::string StringTools::PadRight(const std::string& str, const char pad, const std::size_t len) {
std::stringstream ss;
ss << str;
for (std::size_t i = str.length(); i < len; i++)
ss << pad;
return ss.str();
}

44
StringTools.h Normal file
View File

@ -0,0 +1,44 @@
#ifndef STRINGTOOLS_STRINGTOOLS_H
#define STRINGTOOLS_STRINGTOOLS_H
#include <string>
#include <vector>
/* Handy utensils to manipulate strings */
class StringTools
{
public:
//! Will replace every occurence of `find` in `str` by `subst`.
static std::string Replace(const std::string& str, const char find, const std::string& subst);
//! Will replace every occurence of `find` in `str` by `subst`.
static std::string Replace(const std::string& str, const std::string& find, const std::string& subst);
//! Will replace every occurence of `find` in `str` by `subst`.
static std::string Replace(const std::string& str, const char find, const char subst);
//! Will replace every occurence of `find` in `str` by `subst`.
static std::string Replace(const std::string& str, const std::string& find, const char subst);
//! Will make a string all-lowercase.
static std::string Lower(const std::string& str);
//! Will make a string all-uppercase.
static std::string Upper(const std::string& str);
//! Will split a string by a string seperator
static std::vector<std::string> Split(const std::string& str, const std::string& seperator);
//! Will pad a string to the left to length l
static std::string PadLeft(const std::string& str, const char pad, const std::size_t len);
//! Will pad a string to the right to length l
static std::string PadRight(const std::string& str, const char pad, const std::size_t len);
private:
// No instanciation! >:(
StringTools();
};
#endif //STRINGTOOLS_STRINGTOOLS_H

90
main.cpp Normal file
View File

@ -0,0 +1,90 @@
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <stdio.h>
#include <cstdint>
#include "spell.h"
#include "StringTools.h"
std::string Eval(const std::string& cmd) {
FILE *p;
char ch;
p = popen(cmd.c_str(), "r");
if (p == NULL) {
std::cerr << "Unable to open a process. Make sure the requested program is installed! Tried to call:" << std::endl
<< "'" << cmd << "'" << std::endl;
exit(-1);
}
std::stringstream ss;
while ((ch=fgetc(p)) != EOF )
ss << ch;
// Remove terminating linebreak, if present
std::string out = ss.str();
if ((out.length() > 0) && (out[out.length() - 1] == '\n'))
out = out.substr(0, out.length() - 1);
return out;
}
static const std::vector<std::string> daynths = {
"first",
"second",
"third",
"fourth",
"fifth",
"sixth",
"seventh",
"eighth",
"ninth",
"tenth",
"eleventh",
"twelfth",
"thirteenth",
"fourteenth",
"fifteenth",
"sixteenth",
"seventeenth",
"eighteenth",
"nineteenth",
"twentieth",
"twentyfirst",
"twentysecond",
"twentythird",
"twentyfourth",
"twentyfifth",
"twentysixth",
"twentyseventh",
"twentyeighth",
"twentyninth",
"thirtieth",
"thirtyfirst"
};
int main() {
const std::string weekday = Eval("date +'\%A'");
const std::string month = Eval("date +'\%B'");
const std::string year = spell(std::stoi(Eval("date +'\%Y'")));
const std::string day = daynths[std::stoi(Eval("date +'\%d'"))];
const std::string hour = spell(std::stoi(Eval("date +'\%H'")));
const std::string minute = spell(std::stoi(Eval("date +'\%M'")));
const std::string seconds = spell(std::stoi(Eval("date +'\%S'")));
std::stringstream ss;
ss << "It is "
<< weekday << ", the "
<< day << " of "
<< month << ", " << year << ". "
<< "It is "
<< hour << " " << minute
<< " and "
<< seconds << " seconds.";
std::cout << ss.str() << std::endl;
return 0;
}

56
spell.h Normal file
View File

@ -0,0 +1,56 @@
#include <string>
#include <iostream>
using std::string;
const char* smallNumbers[] = {
"zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen"
};
string spellHundreds(unsigned n) {
string res;
if (n > 99) {
res = smallNumbers[n/100];
res += " hundred";
n %= 100;
if (n) res += " and ";
}
if (n >= 20) {
static const char* Decades[] = {
"", "", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"
};
res += Decades[n/10];
n %= 10;
if (n) res += "-";
}
if (n < 20 && n > 0)
res += smallNumbers[n];
return res;
}
const char* thousandPowers[] = {
" billion", " million", " thousand", "" };
typedef unsigned long Spellable;
string spell(Spellable n) {
if (n < 20) return smallNumbers[n];
string res;
const char** pScaleName = thousandPowers;
Spellable scaleFactor = 1000000000;// 1 billion
while (scaleFactor > 0) {
if (n >= scaleFactor) {
Spellable h = n / scaleFactor;
res += spellHundreds(h) + *pScaleName;
n %= scaleFactor;
if (n) res += " ";
}
scaleFactor /= 1000;
++pScaleName;
}
return res;
}