Validating a password with c++ and giving specific errors - c++

I am trying to write a c++ program that validates a password that requires one uppercase letter, one lowercase letter, and a digit using functions.
The issue is that I'm trying to display the specific errors that are occurring, not just "Invalid, try again.", but I'm having a hard time figuring out how to do that. It should keep asking until they enter a valid password.
#include<iostream>
#include<string>
#include<cctype>
using namespace std;
int validate(string);
string find(int);
int main()
{
string pw;
int val;
string result;
do{
cout << "Enter password: " << endl;
cin >> pw;
val = validate(pw);
cout << find(val) << endl;
} while (val != 0);
}
//VALIDATES PASSWORD
int validate(string pw)
{
int valid = 0;
char c;
int length = pw.length();
bool digit = false;
bool upper = false;
bool lower = false;
int i = 0;
if (pw.length() < 6)
valid = 1;
while (i < pw.length())
{
c = pw[i];
i++;
if (isdigit(c))
{
digit = true;
valid++;
}
if (isupper(c))
{
upper = true;
valid++;
}
if (islower(c))
{
lower = true;
valid++;
}
//Valid input
if (length >= 6 && upper && lower && digit)
valid = 0;
}
return valid;
}
//RETURNS STRING WITH PROBLEM
string find(int valid)
{
string result;
if (valid == 0)
{
result = "Valid Password ";
}
else
{
result = "Invalid Password: ";
if (valid == 1)
result = result + " Too short ";
else if (valid == 2)
result = result + " too short, needs a digit, and an uppercase letter";
else if (valid == 3)
result = result + " too short, needs a digit, and a lowercase letter";
else if (valid == 4)
result = result + " too short, and needs an uppercase letter";
else if (valid == 5)
result = result + " too short, and needs a lowercase letter";
else if (valid == 6)
result = result + " too short, needs a digit";
else if (valid == 7)
result = result + " Needs a didgit ";
else if (valid == 8)
result = result + " Needs digit and uppercase letter ";
else if (valid == 9)
result = result + " Needs digit and lowercase letter";
else if (valid == 10)
result = result + " Needs an uppercase letter ";
else if (valid == 11)
result = result + " Needs uppercase and lowercase letter";
else if (valid == 12)
result = result + " Needs a lowercase letter";
}
return result;
}

I think you are confusing the number of characters (valid) and the type of error -
else if (valid == 9)
result = result + " Needs digit and lowercase letter";
could be produced from 123456abc
As valid == 9 really only counts the characters in the set. Separate counting and whether character classes are used.

It's better to use some flags (bool variables) instead of one number.
If you want to use one number, you must create 2^(things to check) situations
using that number. Here 2^4 = 16 situations is required.
One of the easiest way to mix flags in one number is this:
nth digit = nth flag
for example use this order (length, lower, upper, digit).
So,
to set length validity, add 1000 to number;
to set lower validity, add 100 to number;
to set upper validity, add 10 to number;
to set digit validity, add 1 to number;
Now,
((number)%10 == 1) means digit validity
((number/10)%10 == 1) means upper validity
((number/100)%10 == 1) means lower validity
((number/1000)%10 == 1) means length validity
Following code uses separate flags:
#include<iostream>
#include<string>
using namespace std;
class PasswordStatus
{
bool len, low, up, dig;
//============
public:
PasswordStatus()
{
len = low = up = dig = false;
}
//-----------
void ShowStatus()
{
cout << endl << "Password Status:" << endl;
cout << "Length : " << (len ? "OK" : "Too Short") << endl;
cout << "Contains Lower Case : " << (low ? "Yes" : "No") << endl;
cout << "Contains Upper Case : " << (up ? "Yes" : "No") << endl;
cout << "Contains Digit : " << (dig ? "Yes" : "No") << endl;
}
//-----------
void checkValidity(string pass)
{
int sLen = pass.length();
len = (sLen >= 6);
for(int i = 0; i<sLen; i++)
{
char c = pass[i];
if(!low && islower(c)) {low = true; continue;}
if(!up && isupper(c)) {up = true; continue;}
if(!dig && isdigit(c)) {dig = true; continue;}
}
}
//-----------
bool IsTotalyValid()
{
return low && up && dig && len;
}
};
//====================================================================
int main()
{
PasswordStatus ps;
string pw;
do
{
cout << endl << "Enter password: " << endl;
cin >> pw;
ps.checkValidity(pw);
ps.ShowStatus();
} while (!ps.IsTotalyValid());
cout << "Valid Password : " << pw;
return 0;
}

Related

How do you find the number of occurences of a certain word in a sentence when reading in the sentence character by character?

For example, if I wanted to find the number of times that the word "MY" appears in a user-inputted sentence, how would I do that? Is it even possible to do this if I'm reading in the sentence one character at a time with a while-loop?
Sample input would be something like: "My house is here"
My current output is:
Number of words.........4
Number of uppercase letters.........1
Number of lowercase letters........12
Number of vowels.........6
Number of substring MY.........0
where number of substring MY should be 1.
Here's what I currently have:
#include <iostream>
#include <string>
#include <cstring>
#include <iomanip>
using namespace std;
bool isvowel(char c) {
if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
return true;
} else {
return false;
}
}
int main() {
char c;
int words = 0;
int upperCount = 0;
int lowerCount = 0;
int vowels = 0;
int my = 0;
cout << "Enter a sentence: ";
while (cin.get(c), c != '\n') {
if (isupper(c)) {
upperCount++;
}
if (islower(c)) {
lowerCount++;
}
if (isspace(c)) {
words++;
}
if (isvowel(c) == true) {
vowels++;
}
if (c == 'M' || c == 'm') {
if (c+1 == 'Y' || c+1 == 'y') {
my++;
}
}
}
cout << left << "Number of words" << setfill('.') << setw(10) << right << words + 1 << endl;
cout << left << "Number of uppercase letters" << setfill('.') << setw(10) << right << upperCount << endl;
cout << left << "Number of lowercase letters" << setfill('.') << setw(10) << right << lowerCount << endl;
cout << left << "Number of vowels" << setfill('.') << setw(10) << right << vowels << endl;
cout << left << "Number of substring MY" << setfill('.') << setw(10) << right << my << endl;
system("Pause");
return 0;
}
This can be done in many ways, you almost have one. I will not give you the exact solution but you can try something like this: (written in Java)
// String sentence = "My house is here";
// word = "My"
private int getWordCount(String sentence, String word) {
char[] charArr = sentence.toCharArray();
String currWord = "";
int count = 0;
for(char c : charArr) {
if(c != ' ') { currWord += c; } // if c is not space it gets appended to the current word
else {
if(currWord.toLowerCase().equals(word.toLowerCase())) {
count++;
}
currWord = "";
}
}
return count;
}
Keep a track of the current string. If the current character is not a whitespace, append it to the string; else, the string becomes empty.
For each string, you could compare it to the target string. This comparison will have O(n) complexity, where n is the length of the string.
To optimise it further, you could build a trie for the target string. Since you're already processing one character at a time, the string matching could be done in O(1) instead of O(n).

How to prevent C++ buffer overflow if the user enters two or more strings separated by white spaces?

I'm a student, and I am currently working on C++ Classes. I am making a program which is supposed to ask a user to input a float point number not greater that 99.99 as a price of fuel at a gas station. I have created code that saves the user input in to a char array, and created limits so that the user can't input more than 2 dots, for example (2..2). The maximum number of characters is 5 including one dot. Now, everything works fine except for if the user enters two sets of strings before hitting enter. I have a problem because the second string messes up with other cin statements in the loop.
The code will also take the finalized char array input, and than covert it to a float variable so that the further calculations can be computed easily.
I am working on a Windows system, and Visual Studio 2017 C++.
I have tried detecting the single white space in an if/else statement, but it seems that white space is not detected as a single char array member, like this ex. else if (str[count] == ' ') , and than asking to re enter the correct input without the white space. getline() function could not work on a char array, so I couldn't discard the characters entered after including and after the white space in this way. I have tried changing the char array to a string, but still if the user inputs two or more strings separated by white space, my program keeps reading it in to cin over again.
int main()
{
int count = 0;
int lenFlag = 0, mainFlag = 0;
float result = 0;
int len;
char str[6] = "00000";
//string str ="00000";
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
//This part will ask the user to set the price of fuel
//for the gas pump program. The programming project segment
//is from a book by Walter Savitch "Absolute C++".
while (mainFlag == 0)
{
cout << "Please enter the fuel price in dollars $";
cin >> str;
len = strlen(str);
cout << "strlen is = " << len << endl;
while (len <= 5 && mainFlag == 0)
{
count = 0, lenFlag = 0;
while (count < len && lenFlag == 0)
{
if (count == 0 && (str[count] < 48 || str[count] > 57))
{
cout << "The first input member must be a number."
"You must use a number between 0-9.\n"
"Try again: ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 0 && (str[count] < 48 || str[count] > 57)
&& str[count] != '.')
{
cout << "You must enter number between 0-9, or a decimal delimiter.\n"
"Try again, : ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 0 && (str[0] == '.' && str[1] == '.') || (str[0] == '.' && str[2] == '.') ||
(str[0] == '.' && str[3] == '.') || (str[0] == '.' && str[4] == '.') ||
(str[1] == '.' && str[2] == '.') || (str[1] == '.' && str[3] == '.') ||
(str[1] == '.' && str[4] == '.') || (str[2] == '.' && str[3] == '.') ||
(str[2] == '.' && str[4] == '.') || (str[3] == '.' && str[4] == '.'))
{
cout << "You have entered more than 1 decimal delimiter, try again: ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 1 && str[0] > 48 && str[0] < 58 && str[1]>47
&& str[1] < 58 && str[2]>47 && str[2] < 58)
{
cout << "Maximum number is 99.99, try again:\n";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (str[count] == ' ')
{
cout << "Typing whitspace is not an option!!" << endl;
cout << "Try again!!" << endl;
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count == len - 1 && lenFlag == 0)
{
//cout << "Main flag switches to 1!!" << endl;
mainFlag = 1;
}
count++;
}
} //while(lenCopy <= 5) loop end
if (len > 5)
{
cout << "Either non-numbers were entered, or a negative
number, or an incorrect " << endl;
cout << "number size. Enter a maximum size of 5
including a .dot for decimal number" << endl;
cout << "Maximum number is 99.99." << endl;
mainFlag = 0;
}
}//mainflag loop ends
int dotpos = 0;
for (int n = 0; n < len; n++)
{
if (str[n] == '.')
{
//dotpos = n + 1;
dotpos = len - n - 1;
cout << "dotpos = " << dotpos << endl;
}
else
{
result = result * 10 + (str[n] - '0');
//Line above is a float and character mix as a math equation.
cout << "result " << n << " = " << result << endl;
}
}
if (dotpos > 0)
result = result / (power(10, dotpos));
cout << "You have set the cost at $" << result << " per gallon." << endl;
system("pause");
return 0;
}
Occasional stack around str variable has been corrupted, and that happens when I heavily try to mess with the user input just to check if the program can crash. That's why I need to know how to clear the input after the white space. I solved the stack corruption problem by changing the char array to string, but still not the excess characters that potential users might throw down at the program.
If you must use character arrays, I highly recommend restricting the amount of characters read from the console.
The std::istream::getline() is well suited for this:
const unsigned int LIMIT = 10;
char number_as_text[LIMIT];
std::cout << "Enter a floating point number, less than 10 characters: ";
std::cin.getline(number_as_text, LIMIT);
You can then use a function like strtod to convert the string to floating point variable.
I have found one good way to solve a problem of the string buffer overflow. It uses
cin>>ws; followed by getline() function. The two need to be used in conjunction, and
than the read will be only the first string of characters and everything after the whitespace will be trashed.
cout << "Do you want to set cost in gallons or liters? "
"\nPress G for gallons or L for liters: ";
cin >> ws;
getline(cin, chooseSetCost);
while (chooseSetCost != "G" && chooseSetCost != "g" && chooseSetCost != "L" && chooseSetCost != "l")
{
cout << "Incorrect input. Try again: ";
cin >> ws;
getline(cin, chooseSetCost);
cout << "choose cost is = " << chooseSetCost << endl;
}

Pig latin conversion using Cstrings

The program takes in a word given by the user and translates that to pig latin. I've gotten everything to work almost perfectly, but have run into two bugs. The first of which is when translating words that begin with consonants say "count", the output is "ounttcay" instead of "ountcay". The second bug is that when for three letter words like "egg" or "not" the output is "egg_\377ay" or "ottn\377ay". Is there a simple way to remove that duplicate character and get rid of those numbers?
Note - Unfortunately it has to be done using a Cstring
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
int convertToPigLatin(char arr[50]);
bool isVowel(char ch);
int main() {
char userInput[50];
char answer = ' ';
do {
cout << "Enter a word to convert it to pig latin" << endl;
cin.getline(userInput, 50); //get user input
cout << "Your entered word is " << userInput << endl;
convertToPigLatin(userInput); //translate user's input into piglatin
cout << "Would you like to convert another word?" << endl;
cin >> answer;
cin.ignore(); //clear past user input
cin.clear();
} while (answer == 'Y' || answer == 'y');
return 0;
}
bool isVowel (char ch) {
switch (tolower(ch)) { //if the first character of the given input is a vowel
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return true;
default:
return false;
}
}
int convertToPigLatin(char arr[50]) {
char newArr[50];
// string conjunctions[6] = {"and","but","for","nor","yet","the"}; //list of conjunctions not to be converted
size_t arrLength = strlen(arr); //holds length of input
for (int i = 0; i < arrLength; i++) { //make sure all characters in input are lower case for easier processing
newArr[i] = tolower(arr[i]);
}
char lastChar = newArr[0]; //save the first character in case it needs to be appended
if (atoi(arr) || arr[0] == '\0') { //if the input contains a number or begins with a null character print an error
cout << "Cannot translate inputs that contain numbers" << endl;
return -1;
} else if (arrLength <= 2) { // if the input is 2 or less characters
cout << newArr << endl; //print the input as is
cout << "Boring! Try somthing more than 2 characters long" << endl;
return 0;
} else if ((strstr(newArr, "and") && arrLength == 3) || (arrLength == 3 && strstr(newArr, "but")) || (arrLength == 3 && strstr(newArr, "for")) || (arrLength == 3 && strstr(newArr, "nor")) || (arrLength == 3 && strstr(newArr, "yet")) || (arrLength == 3 && strstr(newArr, "the"))) { //if the input is more than 2 characters long
cout << newArr << endl; //print the input as is
cout << "No conjucntions try again!" << endl;
return 0;
} else { //if the given input is three characters and is not a conjunction, being translation
if (isVowel(arr[0])) { //check if input's first character is a vowel
cout << "Your word in piglatin is "<< strcat(newArr, "ay") << endl; //print that string with 'ay' at the end (i.e. egg'ay')
return 0;
} else { //else if the given input starts with a consonant
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
newArr[arrLength] = lastChar;
}
cout << "Your word in piglatin is " << strcat(newArr, "ay") << endl;
return 0;
}
}
return 0;
}
You're not terminating newArr, and the last index of the input string is arrLength - 1.
int convertToPigLatin(char arr[50]) {
// Make sure newArr is properly terminated.
char newArr[50] = {0};
// [...]
} else { //else if the given input starts with a consonant
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
}
// Do this outside the loop.
newArr[arrLength-1] = lastChar;
// No need for strcat here.
cout << "Your word in piglatin is " << newArr << "ay" << endl;
}
}
return 0;
}
You need to add the '\0' at the end of newArr because strlen does not count it so you are not copying it. strcat replaces '\0' witn 'ay\0' but you have no '\0'.
for (int r = 1; r < arrLength; r++) {
newArr[r-1] = newArr[r];
newArr[arrLength] = lastChar;
}
newArr[arrLength+1] = '\0';
cout << "Your word in piglatin is " << strcat(newArr, "ay") << endl;

Strlen not working when I put it into a function

I am trying to make a password validator that tests for the following criteria:
The password should be at least 8 characters long
The password should contain at least one uppercase and at least one lowercase
The password should have at least one digit
The password should 1 special character: ! # # $ % & * : ;
I got the program to work WITHOUT functions, so I tried to make a function that tests each criteria but for some reason strlen will not work inside my function. I included cstring and cctype but I can't figure out why the error persists. Please help out!
#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;
void criteraValidation(string str1, int up, int low, int digit, int special);
int main()
{
const int SIZE = 20;
char password[SIZE];
int Upper, Lower, Digit, SpecialChar;
cout << "Password Validation Criteria" << endl;
cout << "The password should be at least 8 characters long" << endl;
cout << "The password should contain at least one uppercase and at least one lowercase letter" << endl;
cout << "The password should have at least one digit" << endl;
cout << "The password should 1 special character: ! # # $ % & * : ; " << endl;
do
{
Upper = Lower = Digit = SpecialChar = 0;
cout << "Enter password: ";
cin.getline(password, SIZE);
}
while (SpecialChar == 0 || Upper == 0 || Lower == 0 || Digit == 0 || strlen(password) < 8);
cout << "All crieria have been met! Password: " << password << endl;
return 0;
}
void criteraValidation(string str1, int up, int low, int digit, int special)
{
for (int i = 0; i < strlen(str1); i++)
{
if (isupper(str1[i])) // checks uppercase letters
up++;
if (islower(str1[i])) // checks lowercase letters
low++;
if(isdigit(str1[i])) // checks digits
digit++;
if (ispunct(str1[i])) // checks special characters
special++;
}
if (strlen(str1) < 8)
cout << "Must be at least 8 characters long.\n";
if (up == 0)
cout << "Must be at least 1 uppercase letter.\n";
if (low == 0)
cout << "Must be at least 1 lowercase letter.\n";
if (digit == 0)
cout << "Must have at least 1 digit.\n";
if (special == 0)
cout << "Must have 1 special character" << endl;
}
From the comments, you may want something like this:
void criteraValidation(const string& str1, // Pass by const reference since it won't be modified.
int& up, int& low, int& digit, int& special);
void criteraValidation(const string& str1,
int& up, int& low, int& digit, int& special)
{
up = 0;
low = 0;
digit = 0;
special = 0;
const std::string::size_type length = str1.length();
for (int i = 0; i < length; i++)
{
if (isupper(str1[i])) // checks uppercase letters
up++;
if (islower(str1[i])) // checks lowercase letters
low++;
if(isdigit(str1[i])) // checks digits
digit++;
if (ispunct(str1[i])) // checks special characters
special++;
}
if (str1.length() < 8)
cout << "Must be at least 8 characters long.\n";
if (up == 0)
cout << "Must be at least 1 uppercase letter.\n";
if (low == 0)
cout << "Must be at least 1 lowercase letter.\n";
if (digit == 0)
cout << "Must have at least 1 digit.\n";
if (special == 0)
cout << "Must have 1 special character" << endl;
}
In main:
do
{
Upper = Lower = Digit = SpecialChar = 0;
cout << "Enter password: ";
cin.getline(password, SIZE);
criteraValidation(password, Upper, Lower, Digit, SpecialChar);
}
while (SpecialChar == 0
|| Upper == 0
|| Lower == 0
|| Digit == 0
|| (password.length() < 8));
Note: The isupper, islower, isdigit and ispunct are exclusive (a character can't be both upper and lower case), so you may want to use an if-else-if ladder so that not all comparisons are always executed:
const char c = str1[i];
if (isupper(c))
{
++up;
}
else if (islower(c))
{
++low;
}
else if (isdigit(c))
{
++digit;
}
else if (ispunct(c))
{
++special;
}
else
{
// Put code here for characters not of above types.
}
For example, for the character 'A' only one function is executed, whereas all the comparisons are executed in your code.
your example shows strlen() working on an array of char. When you pass it to a function you're sending in a 'string'. Is that a std::string? do you need to call strlen(str1.c_str())?

Function for getting the ordinal of a number?

I was about to write a C++ function doing the following:
1 ---> "1st"
2 ---> "1nd"
3 ---> "3rd"
...
17657 --> "17657th"
...
i.e. produces the ordinal extension string for that number (it doesn't have to do an itoa() of the number itself). But then I thought "surely something in the standard library or boost does this already?"
Notes:
I know it's not hard to write this, there's an implementation in Python right here on SO, I just don't want to duplicate code.
I need this in English, obviously. A multi-language version would be nice for political-correctness considerations, not more than that...
Here's what I ended up writing:
const char* ordinal_suffix(int n)
{
static const char suffixes [][3] = {"th", "st", "nd", "rd"};
auto ord = n % 100;
if (ord / 10 == 1) { ord = 0; }
ord = ord % 10;
if (ord > 3) { ord = 0; }
return suffixes[ord];
}
The code golf solutions are cute, but - they really do optimize for terseness, not anything else. This is faster (although it could be made even faster by putting the suffixes in a .cpp out of the function body and making the code inlinable), much clearer, and still more terse than most other answers here.
// Returns numbers with ordinal suffix as string
// Based on https://stackoverflow.com/questions/3109978/display-numbers-with-ordinal-suffix-in-php
std::string NumberToOrdinal(size_t number) {
std::string suffix = "th";
if (number % 100 < 11 || number % 100 > 13) {
switch (number % 10) {
case 1:
suffix = "st";
break;
case 2:
suffix = "nd";
break;
case 3:
suffix = "rd";
break;
}
}
return std::to_string(number) + suffix;
}
I'm pretty sure you can adapt the four line solution at Display numbers with ordinal suffix in PHP. Unfortunately, I don't think there is such a thing in a common C++ lib.
try this...
#include <iostream>
using namespace std;
void suffix(int n, char suff[]);
// creates the ordinal suffix
// for a given number
int main()
{
char s[5];
int x;
cout << "Enter a number to find the ordinal suffix for ";
cin >> x;
suffix(52111,s);
}
void suffix(int n, char suff[])
{
if(n%100 == 11 || n%100 == 12 || n%100 == 13)
{
cout << "suffix is: " << n << "th";
cout << endl;
}
else
{
if(n%10 == 1)
{
cout << "Suffix is: " << n << "st";
cout << endl;
}
else
{
if(n%10 == 2)
{
cout << "Suffix is: " << n << "nd";
cout << endl;
}
else
{
if(n%10 == 3)
{
cout << "Suffix is: " << n << "rd";
cout << endl;
}
else
{
if(n%10 == 4 || n%10 == 5 || n%10 == 6 || n%10 == 7 || n%10 == 8 || n%10 == 9 || n%10 == 0)
{
cout << "Suffix is: " << n << "th";
cout << endl;
}
}
}
}
}
}
I used the following string function to accomplish it.
#include <string>
#include <iostream>
using namespace std;
string ordinal(int i)
{
if(i==1)
{
return "First";
}
if(i==2)
{
return "Second";
}
if(i==3)
{
return "Third";
}
if(i==4)
{
return "Fourth";
}
if(i==5)
{
return "Fifth";
}
if(i==6)
{
return "Sixth";
}
if(i==7)
{
return "Seventh";
}
if(i==8)
{
return "Eighth";
}
}
int main()
{
for(int i=0; i<8; i++)
{
cout << ordinal(i+1) << " number: ";
}
return 0;
}
#include <iostream>
#include <string>
std::string number_to_ordinal(int number)
{
// Convert number to string
std::string ordinal = std::to_string(number);
// Get the last character of the number to later determine ordinal indicator
char last_char = ordinal.back();
// Get the last two characters of the number to deal with ordinal indicator conditions
std::string last_two_char;
if(ordinal.size() > 1)
last_two_char = ordinal.substr(ordinal.size() - 2, ordinal.size());
// Determine ordinal indicator. Each number with a last character ending in '1', '2',
// and '3' require ordinal indicators of 'st', 'nd', and 'rd', respectively. However,
// numbers with the last two characters ending in '11', '12', and '13' require 'th'
// as the ordinal indicator.
if(last_two_char != "11" && last_char == '1')
ordinal += "st";
else if (last_two_char != "12" && last_char == '2')
ordinal += "nd";
else if (last_two_char != "13" && last_char == '3')
ordinal +="rd";
else
ordinal += "th"; // All other numbers require 'th' as the ordinal indicator
return ordinal;
}
///////////////////////////////////////////////////////////////////////
// Main Program
///////////////////////////////////////////////////////////////////////
int main()
{
// Test number to ordinal
for(int i = 17657; i < 17725; i++)
std::cout << number_to_ordinal(i) << std::endl;
return 0;
}