A few errors - trying to convert Roman entry to Decimal - c++

Just going to change my question for now - I could just use some guidance as to why I have three compiler errors in my program, not quite sure what I did wrong/am missing - I have added comments into the code just to state where they are. Thanks
#include <iostream>
#include <string>
using namespace std;
class romanType
{
public:
void setRomanNum(string store);
// this function will store the Roman numeral
int convertNum(char rNum);
// this function will convert the Roman numeral to a decimal
void decimalPrint(int total);
// this function will print the decimal number
void romanPrint(char rNum);
// this function will print the Roman numeral
int getNum(char letter);
// this function will get the number input
romanType(int store);
//Constructor with parameter
romanType();
char roman[7];
string num;
int length = 0;
string dNum;
int equals;
};
romanType::romanType(int store)
{
dNum = 1;
}
void romanType::setRomanNum (string store)
{
dNum = store;
}
void romanType::romanPrint(char rNum)
{
cout << "The Roman numeral is: " << roman << endl;
}
void romanType::decimalPrint(int total)
{
cout << "The Decimal number is: " << equals << endl;
}
int romanType::convertNum (char rNum)
{
int letter;
int totalNum = 0;
for (int i = 0; i< dNum.length(); i++)
// "loop will run at most once (loop increment never executed)"?
{
switch (roman[i])
{
case 'M':
totalNum+= 1000;
break;
case 'D':
totalNum += 500;
break;
case 'C':
totalNum += 100;
break;
case 'L':
totalNum += 50;
break;
case 'X':
totalNum += 10;
break;
case 'V':
totalNum += 5;
break;
case 'I':
totalNum += 1;
break;
}
totalNum = totalNum + letter;
equals = totalNum;
return equals;
}
};
// "control may reach end of non-void function"
int main()
{
romanType output;
int rNumeral;
char entry;
cout << "Please enter a Roman numeral (Capitalized only): " << endl;
cin >> rNumeral;
cout << "Print Decimal or Roman Numeral? Type 1 for Decimal, 2 for Roman Numeral: " << endl;
cin >> entry;
if (entry == '1')
{
cout << "You chose to view the decimal conversion." << endl;
output.decimalPrint(rNum);
// How do I output the decimal conversion from the void romanType::decimalPrint(int total) function?
}
else if (entry == '2')
{
cout << "You chose to view the Roman numeral." << endl;
output.romanPrint(rNumeral);
}
else
cout << "Error: bad input" << endl;
return 0;
exit(1);
}

The mistake in the algorithm is that the Roman system is non-positional. See en.wikipedia.org/wiki/Roman_numerals and en.wikipedia.org/wiki/Subtractive_notation. You can't just add up consequent digits (i.e. letters) but you also have to identify and account for the cases when subtraction takes place.
why am I getting the error "no matching constructor for initialization of "roman type"?
Because the only provided constructor is not the default one, but takes one parameter of type int. Since such a constructor was provided, the default constructor wasn't generated by the compiler. Define romanType::romanType() or change the existing one to romanType::romanType(int i = 0) (add a default parameter). See Is there an implicit default constructor in C++? and why default constructor is not available by default in some case
expected expression?
Provide braces around the preceding else block. More than one statement -> braces required.
if (entry == '1') {
cout << "You chose to view the decimal conversion." << endl;
output.decimalPrint(rNum);
} else if (entry == '2')
cout << "You chose to view the Roman numeral." << endl;
output.romanPrint(rNumeral);
}
"control may reach end of non-void function"
This is a warning only, but it will turn into an error if you include the -Werror flag that tells the compiler to treat all warnings as errors.
Ok I was wrong on this one. Actually the trick is that it is (in theory) possible that the romanType::convertNum(int) function follows a route where the for loop will never get executed and thus no return statement will be executed either. That's bad since the function is declared to return int hence there must be present an explicit return statement that (surprise) would return a value. Move the return out of the loop. This error is also closely related to the next one, discussed below.
"loop will run at most once (loop increment never executed)"?
This is because the return statement is placed incorrectly: inside the for loop not outside of it, and inside the function body. Hence the loop runs once and the function returns. Move the return statement. Credit to #ATN_LR_boom for noticing this!
Also, please get in the habit of formatting code properly. It will save you a lot of headache down the way.
Other than that, I'd use a std::map for the conversion function, it's shorter and more clear to the reader compared to the switch statement. Something along the lines of
int romanType::convertNum(int rNum) {
const static std::map<char, int> conversion = {
{'M', 1000},
{'D', 500},
// more mappings
{'I', 1}
};
if ((auto it = conversion.find(rNum)) != conversion.end())
return it->second;
else
return -1;
}

Your logic for the switch is wrong, try something like this:
int totalNum = 0;
for (int i = 0; i< dNum.length(); i++)
// the loop ran once because you were returning values when catching a letter
{
switch (roman[i])
{
case 'M': // roman[i] is a char, the cases should try to catch chars
totalNum += 1000; // increment your global number
break;
case 'D':
totalNum += 500;
break;
...
}
return totalNum;

Related

Roman Numeral to Integer Conversion Problem

I am so close to solving this roman numeral to integer problem. However, in my if statement for when character equals M, I am getting an error thrown when declaring my previous variable when the input is MCMXCIV for example. Because there is nothing before M, it is throwing an out-of-bounds error. How can I fix this?
#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
using namespace std;
//Character to search and add to the integer
char character;
//The integer value that is needed to add up and output the corresponding value
int integer = 0;
//One of the test runs and what will be needed for every special case
int main()
{
//Roman numeral given
string input;
//Prompt for user to enter the roman numeral integer
cout << "Enter the roman numeral you want to convert into a number: " << endl;
cin >> input;
cout << input << " is what you are wanting to convert." << endl;
//Read through the string that is being inputted then assign values to the overall integer
for (int i = 0; i < input.length(); i++)
{
character = input.at(i);
cout << "This is the character that is being read right now: " << character << endl;
//Arithmitic for when the character is found and the corresponding value needs to be added
if(character == 'I')
{
integer+=1;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'V')
{
char previous = input.at(i-1);
integer+=5;
if(character == 'V' && previous == 'I')
{
integer = integer - 2;
}
cout << "Integer value now: " << integer << endl;
}
else if(character == 'X')
{
integer+=10;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'L')
{
integer+=50;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'C')
{
integer+=100;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'D')
{
integer+=500;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'M')
{
char previous = input.at(i-1);
integer+=1000;
if(character == 'M' && previous == 'C')
{
integer -= 200;
}
cout << "Integer value now: " << integer << endl;
}
}
cout << "The integer value is: " << integer << endl;
}
First of all: Good that you used the at() function. So you could detect the "out of bounds" problem.
in char previous = input.at(i - 1);, variable "i" could be 0 and you then try to access array element "-1", which is of course out of bounds for your use case.
So, you need an additional check, if "i" greater then 0, before subtracting.
But in general, your approach is too complicated. You can make your life easier, by analyzing or reading, how roman numerals are defined. Look for example here. And please read especially about the "subtractive notation".
You already noticed that but, unfortunately, your implementation is not always following that rule. You made the check only for "M" and "V". But basically, you need to do that for all literals (except "I").
You can boil down this to the rule:
If a literal before a following literal is less, then use the subtrative form. Or, even better, you can read from right to left and finally say:
"If the current literal is less than the follwoing, then use the subtractive form."
And what is the subtractive form? We can simply add the negative number. Example, using number 94 which is "XCIV". We start summing up from the right:
Start. Begin from right. Initialize sum with rightmost value: Looking at 'V': sum = 5
Next: Read 'I'. Check, if this is less than the following literal 'V'. Yes, it is. So, use subtractive form. Add the negative. Now sum = sum + (-1), sum = 4
Now: Read 'C'. Check, if this is less than the following literal 'I'. No, it is not. So, simply add the positive value. Now sum = sum + 100, sum = 104
Next: Read 'X'. Check, if this is less than the following literal 'C' . Yes, it is. So, use subtractive form. Add the negative. Now sum = sum + (-10), sum = 94
So, this is now a very simply algorithm. We will convert a roman literal (one letter) to a integer and then build a sum with positive or negative values.
One of many many potential implementations could look like this:
#include <iostream>
#include <string>
int convert(char romanLiteral) {
switch (romanLiteral) {
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
default:
return 0;
}
}
int romanLiteralStringToInteger(const std::string& romanLiteralString) {
// Sanity check:
if (romanLiteralString.empty()) return 0;
// Get length of input string
int lengthOfRomanLiteralString = static_cast<int>(romanLiteralString.length());
// Initialize sum with rightmost value
int sum = convert(romanLiteralString[lengthOfRomanLiteralString-1]);
// Now iterate over the string form right to left
for (int i = lengthOfRomanLiteralString - 2; i >= 0; --i) {
// Check if this literal is less than the following
if (convert(romanLiteralString[i]) < convert(romanLiteralString[i+1]))
sum -= convert(romanLiteralString[i]);
else
sum += convert(romanLiteralString[i]);
}
return sum;
}
int main() {
std::string romanNumber = "XCIV";
std::cout << romanNumber << " --> " << romanLiteralStringToInteger(romanNumber) << '\n';
}
In C++ you would probably use associative containers like std::map or std::unordered_map for converting one literal to a number. And maybe a ternary operator, instead of an if.
Then the problem could be implemented like the following:
#include <iostream>
#include <string>
#include <unordered_map>
int romanLiteralStringToInteger(const std::string& romanLiteralString) {
if (romanLiteralString.empty()) return 0;
std::unordered_map<char, int> T = { { 'I' , 1 }, { 'V' , 5 }, { 'X' , 10 }, { 'L' , 50 }, { 'C' , 100 }, { 'D' , 500 }, { 'M' , 1000 } };
int sum = T[romanLiteralString.back()];
for (int i = romanLiteralString.length() - 2; i >= 0; --i)
sum += (T[romanLiteralString[i]] < T[romanLiteralString[i + 1]] ? -T[romanLiteralString[i]] : T[romanLiteralString[i]]);
return sum;
}
int main() {
std::string romanNumber = "XCIV";
std::cout << romanNumber << " --> " << romanLiteralStringToInteger(romanNumber) << '\n';
}
And the hardcore solution with a stateful lambda.
#include <iostream>
#include <string>
#include <unordered_map>
#include <numeric>
#include <iterator>
std::unordered_map<char, int> ARTI{{'I',1 },{'V',5 },{'X',10 },{'L',50 },{'C',100},{'D',500 },{'M',1000 }};
int main() {
std::string romanNumber = "XCIV";
std::cout << std::accumulate(std::next(romanNumber.rbegin()), romanNumber.rend(), ARTI[romanNumber.back()], [&, next = ARTI[romanNumber.back()]](const int s, const char c) mutable {
int sum = s + (ARTI[c] < next ? -ARTI[c] : ARTI[c]); next = ARTI[c]; return sum; });
}

How can I throw a error if the user enters more than one integer

So this is my code:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
long int iterFunc(int);
long int recurFunc(int);
int main() {
int n;
while(true){
try{
cout << "Enter: ";
if (!(cin >> n))
throw("Type Error");
if (n < 0)
throw n;
else
if (n == 0)
break;
cout << "Iterative: " << iterFunc(n) << endl;
cout << "Recursive: " << recurFunc(n) << endl;
}
catch(int n){
cout << "Error. Enter positive number." << endl;
}
catch(...){
cin.clear();
cin.ignore(100, '\n');
cout << "Error. Please enter a number" << endl;
}
}
cout << "Goodbye!";
return 0;
}
long int iterFunc(int n){
vector<long int> yVec = {1, 1, 1, 3, 5};
if (n <= 5)
return yVec[n - 1];
else
for(int i = 5;i < n; i++){
long int result = yVec[i - 1] + 3 * yVec[i- 5];
yVec.push_back(result);
}
return yVec.back();
}
long int recurFunc(int n){
switch (n) {
case 1:
case 2:
case 3:
return 1;
break;
case 4:
return 3;
break;
case 5:
return 5;
break;
default:
return recurFunc(n - 1) + 3 * recurFunc(n - 5);
break;
}
}`
The program shoud accept only one integer and return the y of the function using both iterative and recursive implemetations. Ex.: 30, 59, 433. How can I throw an error message if the user enters more then one integer, separated by space? Ex.: '3 45 32'.
I tried using if (cin.getline == ' ') throw("Error name") but the program still executes and return the y of the function for number in the input
Something like this works:
int main()
{
std::string str;
std::cout << "? : ";
std::getline(std::cin, str);
std::string::size_type pos(0);
int i = std::stoi(str, &pos);
if (pos != str.length())
return 1;
}
I found a part of my old code that might come in handy.
int val;
do
{
cin>>val;
if(!cin){ //you can add more conditions here
cin.clear();
cin.sync();
/* additional error handling */
}
else{
break; //input is correct - leaving loop
}
}while(true); //or here
Basically what !cin does is - it checks what type of value you actually want to write to, because it's needed anyway to figure out if data type is written to the correct type of our val. This means, that "30" or "433" etc. are integers (correct), "s" or "string" etc. are strings (or char*, correct me if I am wrong) (incorrect).
This also means, that "3 45 32" should be interpreted as string, which should result in another loop run.
Note: I didn't really test this code, so it might be completely wrong.
Edit: Okay now after some tests I realised this code needs some retweaking.
Firstly, "3 45 32" is not interpreted as string (now understandable). Instead, first number (before whitespace) is saved as an integer and all other numbers are stored in the buffer (next cin will be filled with it), which we can avoid using cin.clear() and cin.sync() once again.
The question is - is it okay for you to accept the first integer and ignore everything after the first whitespace? If not, you will have to save the input as string and extract whatever data you want from it.
I am leaving the original answer as is for simplicity of finding references in this edit.

C++ switch statement odd output

I'm working on a final assignment for an Intro to C++ course. What I've coded so far works, but it's producing some interesting output that I'm looking for clarification on. Here's my code:
(Caveat: Yes, I know using void main() sucks, but we're using Visual Studio in class, and this is the instructors preference.)
#include <string>
#include <iostream>
using namespace std;
void conversion(int);
void main()
{
int decimal_number, answer;
cout << "Please enter a whole decimal number (e.g. 20): ";
cin >> decimal_number;
if (decimal_number == 0)
{
answer = 0;
cout << "The hexadecimal value of your number is: " << answer;
getchar();
getchar();
}
else if (decimal_number < 0)
{
cout << "INVALID ENTRY" ;
getchar();
getchar();
}
else if (decimal_number > 0)
{
conversion(decimal_number);
}
getchar();
getchar();
}
void conversion (int decimal_number)
{
int count = 0, remainder, reverse_order;
char hexadecimal_number[10] = { NULL };
while (decimal_number != 0)
{
remainder = decimal_number % 16;
switch (remainder)
{
case 0:
hexadecimal_number[count] = '0';
count++;
break;
case 1:
hexadecimal_number[count] = '1';
count++;
break;
case 2:
hexadecimal_number[count] = '2';
count++;
break;
case 3:
hexadecimal_number[count] = '3';
count++;
break;
case 4:
hexadecimal_number[count] = '4';
count++;
break;
case 5:
hexadecimal_number[count] = '5';
count++;
break;
case 6:
hexadecimal_number[count] = '6';
count++;
break;
case 7:
hexadecimal_number[count] = '7';
count++;
break;
case 8:
hexadecimal_number[count] = '8';
count++;
break;
case 9:
hexadecimal_number[count] = '9';
count++;
break;
case 10:
hexadecimal_number[count] = 'A';
count++;
break;
case 11:
hexadecimal_number[count] = 'B';
count++;
break;
case 12:
hexadecimal_number[count] = 'C';
count++;
break;
case 13:
hexadecimal_number[count] = 'D';
count++;
break;
case 14:
hexadecimal_number[count] = 'E';
count++;
break;
case 15:
hexadecimal_number[count] = 'F';
count++;
break;
default:
cout << decimal_number << "+++ " << hexadecimal_number;
cout << "INVALID ENTRY";
getchar();
getchar();
}
decimal_number = decimal_number / 16;
}
cout << "The hexadecimal value of your number is: ";
for (reverse_order = count -1; reverse_order >= 0; reverse_order--)
{
cout << hexadecimal_number[reverse_order];
}
getchar();
getchar();
}
So, like I said: my code works. I can take any number input as a decimal, and convert it to its hexadecimal equivalent. However, I've found that I've had to include an IF statement within the main function of the code, because if the user inputs anything other than a decimal number into the decimal_number variable, the program will store a string of decimal numbers, into decimal_number, and I have no idea where those numbers come from. They don't appear to be the ASCII equivalents of anything.
... If none of this makes any sense, I'm sorry. just input cout << decimal_number after the line cin >> decimal_number, then run the code and see what weird number comes out. I hope that makes things clearer.
Anyway, my instructors stumped, and I'm stumped. I've got the above workaround in place that the instructor will accept, but for my own sanity, I just want to figure out what's going on. Any help or pointers is appreciated. Cheers!
You can test whether the result of cin >> decimal_number succeeded, like
if(!(cin>>decimal_number))
throw std::runtime_error("Oops, not a decimal number!");
This is a bit too extreme, you can also validate the input:
while(!(cin>>decimal_number))
{
std::cout << "Not decimal, input again ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
If you're not performing this kind of validation, then you leave the stream in an invalid state whenever reading a non-decimal, and the variable you think you're reading into will end up un-initialized.
However, I've found that I've had to include an IF statement within the main function of the code, because if the user inputs anything other than a decimal number into the decimal_number variable, the program will store a string of decimal numbers, into decimal_number, and I have no idea where those numbers come from.
Well, you did not initialise decimal_number to anything, and you do not have any error checking around the cin >> decimal_number call. So I'm not sure what else you expected but an unspecified value for decimal_number!
Your instructor should know this. It's worrying that, on top of teaching you to write code that is ill-formed per the International Standard (void main!!), they failed to discover this problem or note that you have no error checking.
What's the point of the assignment?
The conversion can be simplified to:
cout << hex << decimal_value << endl;
Or if you need it in a string:
std::string convert_decimal_to_hex_string(int decimal_value)
{
std::ostringstream output;
output << hex << value;
return output.str();
}
I believe the class should show you how to use std::string and existing language features (such as the hex manipulator). Using char for a string is dangerous.
Also, since you don't know the size or limit of the decimal values, you will need to dynamically allocate (i.e. during run-time) the array holding the characters. Think about allocating 2 characters and entering the value 1024; buffer overflow.
Change your program to use std::string. Refrain from character (C-Style) arrays.

Issues with Typedef - need to ignore certain code

Here's my biggest problem.
I'm working on a program that does a bunch of fast sorting algorithms. (Quick, Radix, and Merge).
However, I want to sort multiple types of data (lists of integers and strings, in particular). Therefore I decided to use Typedef in order to make my key variables able to change types.
In the Radix code, I have an area where I need to do integer mathematics. I wrote a version for integers, and a version for strings. (In the string version, I use stoi()).
When I want to run the program using Integers, I need it to ignore areas of code that require stoi() conversion.
How can I make the compiler ignore code conditionally depending on what is in my typedef statement?
EDIT: I took the suggestion of using #ifndef to hide sections of code, for now because I primarily want to debug my code right now. (My Radix Sort is not working with strings.)
I'll try to work out the kinks of Template once all my code is working!
As requested, here is the code. Did not include code for actual functions.
#include<iostream>
#include<ctime>
#include<cmath>
#include<fstream>
#include<stdlib.h>
#include<string>
#include"Queue.h"
using namespace std;
// Global variables
ItemType Data[100000]; // Data array
Queue QArray[26]; // Array of Queues. 0-9 used for numbers, 0-25 used for characters/strings
// Functions
void QuickSort(ItemType Data[], int Lower, int Upper);
int Partition(ItemType Data[], int Lower,int Upper);
void RadixSort(ItemType Data[], int counter, int digits);
void MergeSort(ItemType Data[], int Lower, int Upper);
void Merge(int Lower, int Mid, int Upper);
// Main
int main()
{
// Initialize and open the text files
ifstream NumberInput, StringInput;
ofstream QuickNumOut, QuickStrOut, RadixNumOut, RadixStrOut, MergeNumOut, MergeStrOut;
NumberInput.open("Numbers.txt");
StringInput.open("Strings.txt");
QuickNumOut.open("QuickSortedNumbers.txt");
QuickStrOut.open("QuickSortedStrings.txt");
RadixNumOut.open("RadixSortedNumbers.txt");
RadixStrOut.open("RadixSortedStrings.txt");
MergeNumOut.open("MergeSortedNumbers.txt");
MergeStrOut.open("MergeSortedStrings.txt");
// Declare the variables
time_t totaltime; // Used to calculate run time of algorithms
int counter = 0; // Counter for items
int choice, type; // User chooses string or integer sort, and type of sort
ItemType max; // Largest number, used for Radix sort
int digits = 0; // Finds number of digits in max, for Radix sort
cout << "Would you like to sort the list of (1) Numbers, or (2) Strings? ";
cin >> choice;
cout << "Would you like to use (1) Quick Sort, (2) Radix Sort, or (3) Merge Sort? ";
cin >> type;
switch(type)
{
case 1:
{
// Switch statement to read information into array from the text files
switch (choice)
{
case 1:
{
// While loop reads in data until end of file is found
while(!NumberInput.eof())
{
NumberInput >> Data[counter];
counter++;
}
break;
}
case 2:
{
// While loop reads in data until end of file is found
while(!StringInput.eof())
{
StringInput >> Data[counter];
counter++;
}
break;
}
}
// Close input files
NumberInput.close();
StringInput.close();
// Start timer
totaltime = time(0);
// Perform QuickSort
QuickSort(Data, 0, counter-1);
// Stop timer
totaltime = time(0) - totaltime;
// Switch statement to print sorted list to text files
switch (choice)
{
case 1:
{
// For loop goes from 0 to the length of actual data in the array
for (int i = 0; i < counter; i++)
QuickNumOut << Data[i] << endl;
break;
}
case 2:
{
// For loop goes from 0 to the length of actual data in the array
for (int i = 0; i < counter; i++)
QuickStrOut << Data[i] << endl;
break;
}
}
// Print out information
cout << "QuickSort data written to file." << endl;
cout << "Total time for QuickSort was " << totaltime << " seconds." << endl << endl;
break;
}
case 2:
{
// Reset counter
counter = 0;
// Reopen files
NumberInput.open("Numbers.txt");
StringInput.open("Strings.txt");
// Switch statement to read information into array from the text files
switch (choice)
{
case 1:
{
max = Data[0];
// While loop reads in data until end of file is found
while(!NumberInput.eof())
{
NumberInput >> Data[counter];
if (Data[counter] > max)
max = Data[counter];
counter++;
}
break;
}
case 2:
{
/*
max = Data[0];
// While loop reads in data until end of file is found
while(!StringInput.eof())
{
StringInput >> Data[counter];
if (Data[counter] > max)
max = Data[counter];
counter++;
}*/
break;
}
}
// Find out how many digits are in largest number
while (max)
{
max /= 10;
digits++;
}
// Close input files
NumberInput.close();
StringInput.close();
// Start timer
totaltime = time(0);
// Perform QuickSort
RadixSort(Data, counter, digits);
// Stop timer
totaltime = time(0) - totaltime;
// Switch statement to print sorted list to text files
switch (choice)
{
case 1:
{
// For loop goes from 0 to the length of actual data in the array
for (int i = 0; i < counter; i++)
RadixNumOut << Data[i] << endl;
break;
}
case 2:
{
// For loop goes from 0 to the length of actual data in the array
for (int i = 0; i < counter; i++)
RadixStrOut << Data[i] << endl;
break;
}
}
// Print out information
cout << "RadixSort data written to file." << endl;
cout << "Total time for RadixSort was " << totaltime << " seconds." << endl << endl;
break;
}
case 3:
{
// Reset counter
counter = 0;
// Reopen files
NumberInput.open("Numbers.txt");
StringInput.open("Strings.txt");
// Switch statement to read information into array from the text files
switch (choice)
{
case 1:
{
// While loop reads in data until end of file is found
while(!NumberInput.eof())
{
NumberInput >> Data[counter];
counter++;
}
break;
}
case 2:
{
// While loop reads in data until end of file is found
while(!StringInput.eof())
{
StringInput >> Data[counter];
counter++;
}
break;
}
}
// Close input files
NumberInput.close();
StringInput.close();
// Start timer
totaltime = time(0);
// Perform QuickSort
MergeSort(Data, 0, counter-1);
// Stop timer
totaltime = time(0) - totaltime;
// Switch statement to print sorted list to text files
switch (choice)
{
case 1:
{
// For loop goes from 0 to the length of actual data in the array
for (int i = 0; i < counter; i++)
MergeNumOut << Data[i] << endl;
break;
}
case 2:
{
// For loop goes from 0 to the length of actual data in the array
for (int i = 0; i < counter; i++)
MergeStrOut << Data[i] << endl;
break;
}
}
// Print out information
cout << "MergeSort data written to file." << endl;
cout << "Total time for MergeSort was " << totaltime << " seconds." << endl << endl;
break;
}
default:
{
cout << "Invalid choice.";
break;
}
}
// Close output files
QuickNumOut.close();
QuickStrOut.close();
RadixNumOut.close();
RadixStrOut.close();
system("PAUSE");
return 0;
}
I just noticed that you handle the type recognition within an switch and not with a typedef (like you hinted in your subject). In that case - use template functions. It's really easy to implement - for example QuickSort will become:
template <typename T>
void QuickSort(T Data[], int Lower, int Upper)
{
// Your current code operating on 'T' instead of 'int'/'string'
}
And so on. This solution will shorten your code by a ton.
And then you just use it like this:
switch(type){
case 1:
QuickSort<int>(table,lower,upper);
break;
case 2:
QuickSort<string>(table,lower,upper);
}
Also - use containers instead of the array to make things even more simple. I would suggest std::vector.
You can pre-processor a section out of your code using something like:
#define IGNORE_STOI
...
#ifndef IGNORE_STOI
// string to int section of code
#endif
This will remove the section between the #ifndef and #endif statements if IGNORE_STOI is defined.

getline() omits first letter of my output from array.

I'm coding a simple Mad Libs program for school. The code I'm posting iterates through an array searching for certain prompts. Once found it uses the prompt to ask a question and records the answer. The array that holds my answers however, is omitting the first letter of every word except for the very first variable. Here is my code and a copy of the output from the array. It's shite I know, but I'm learning.
char buffer[256];
int y = 0;
//iterates through array looking for answers
for(int i = 0;i <= 256;i++)
{
if(storyArray[i][0] == '<' && isalpha(storyArray[i][1]))
{
for(int x = 0; storyArray[i][x]; x++)
{
switch(storyArray[i][x]){
case '<':
cout << "\t";
x++;
putchar(toupper(storyArray[i][x]));
break;
case '>':
cout << ": ";
cin.ignore();
cin.getline(buffer,256);
strcpy(answerArray[y],buffer);
y++;
break;
case '_':
cout << " ";
break;
default:
cout << storyArray[i][x];
break;
}
}
}
}
Output:
Arrayitem1
rrayitem2
You're telling it to miss the first character. That's what this does:
cin.ignore();
Take that out and you'll be fine.