Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <string>
- using namespace std;
- // Because the quiz specifies that all the functions should not return a value, we use
- // reference variables when the larger program needs to use the work done inside a function.
- // Otherwise, we pass by value to make debugging easier.
- // These functions get input that is used by other functions, so the functions need to
- // write to those variables. They are passed by reference.
- void validateUserName(string &userName);
- void validateUserInput(string &userInput);
- // The output file has to be available to the function that actually writes
- // data into the file, so outputFile is passed by reference.
- void createFile(string userName, ofstream &outputFile);
- // My compiler required outputfile to be a reference variable. I thought maybe I could get away
- // with passing the file object by value and still have the function write to the actual file,
- // but I guess it doesn't work that way.
- void writeDataToFile(string userInput, ofstream &outputfile);
- // We are only reading from the input File so userName (which is the filename on disk)
- // can be passed by value. The ifstream object is instantiated inside this function,
- // all we need back is the contents of the file as a string.
- void readDataFromFile(string &fileData, string userName);//read from the file
- // These functions don't modify the fileData, but they will create the strings containing
- // how many even digits and odd digits there are. So fileData is passed by value and
- // the digits to be printed are passed by reference.
- void checkEvenDigit(string fileData, string &evenDigits);
- void checkOddDigit(string fileData, string &oddDigits);
- // Other functions generate the strings to output, this function is only the statements
- // to output to the screen, so they only need to be passed by value.
- void displayResults(string evenDigits, string oddDigits);
- int main() {
- // User input
- // userName will also be the filename of the file we write and read to
- string userName, userInput;
- // Data we'll read back from the output file
- string fileData;
- // Even and odd digits to be printed
- string evenDigits, oddDigits;
- // The output filestream object we use to write the output file
- ofstream outputFile;
- // The input filestream object we use to read back from the output file
- ifstream inputfile;
- // Get input and validate it
- validateUserName(userName);
- validateUserInput(userInput);
- // Create, open, and write to the output file
- createFile(userName, outputFile);
- writeDataToFile(userInput, outputFile);
- // Read the data back from the file we just wrote
- readDataFromFile(fileData, userName);
- // Get even and odd digits
- checkEvenDigit(fileData, evenDigits);
- checkOddDigit(fileData, oddDigits);
- //Output the information about even and odd digits
- displayResults(evenDigits, oddDigits);
- return 0;
- }
- void validateUserName(string &userName){
- int counter;
- unsigned long int userNameLength;
- bool userNameIsValid;
- // Loop to read user input
- do {
- cout << "Please enter your name: ";
- getline(cin, userName);
- userNameLength = userName.length();
- userNameIsValid = true;
- counter = 0;
- // Someone's name can have all kinds of letters, punctuation, and
- // and spaces ("Martin Luther King, Jr."), but there shouldn't be any numbers
- // ("Paco Ignacio Taibo II", not "Paco Ignacio Taibo the 2nd") or newlines.
- // Nested loop to check each character from input and make sure it's not a number
- while (counter < userNameLength && userNameIsValid == true){
- if (isnumber(userName[counter])) {
- cout << "Sorry, that does not appear to be a real name." << endl;
- userNameIsValid = false;
- }
- counter++;
- }
- } while (userNameIsValid == false);
- }
- void validateUserInput(string &userInput){
- string currentLine;
- bool sentinelEncountered = false;
- cout << "Now you can enter any text you want (including whitespace), but I'm "
- "going to stop reading when you type \"-1\" on its own line. Also, "
- "your input can't just be blank besides \"-1\":";
- // When the sentinel "-1" is encountered, the boolean is set to end the loop.
- do {
- getline(cin, currentLine);
- if (currentLine == "-1") {
- sentinelEncountered = true;
- } else {
- userInput.append(currentLine);
- userInput.append("\n");
- }
- // check to make sure input wasn't blank. Counts whitespace, so if a user just
- // enters a few newlines or tabs, the program will proceed.
- if (userInput.empty()){
- cout << "Your input cannot be blank, it was pretty much the only rule "
- "I gave you. Please enter some text, and I'll stop reading when "
- "you type \"-1\" on its own line:";
- sentinelEncountered = false;
- }
- } while (sentinelEncountered == false);
- }
- void createFile(string userName, ofstream &outputFile){
- outputFile.open(userName);
- }
- void writeDataToFile(string userInput, ofstream &outputFile){
- outputFile << userInput;
- outputFile.close();
- }
- void readDataFromFile(string &fileData, string userName){
- ifstream inputFile;
- string currentLine;
- inputFile.open(userName);
- while ( inputFile >> currentLine){
- fileData.append(currentLine);
- }
- inputFile.close();
- }
- void checkEvenDigit(string fileData, string &evenDigits){
- unsigned long int fileDataLength = fileData.length();
- unsigned long int counter;
- unsigned long int evenCount = 0;
- unsigned short int digit;
- string digitAsString;
- for (counter = 0; counter < fileDataLength; counter++){
- // Only try to get evenness if we're dealing with an actual integer
- if (isnumber(fileData[counter])) {
- digit = fileData[counter];
- // If a number is even, add it to our string we'll eventually output
- if (digit % 2 == 0){
- // You can't use string.append() with an integer, so we have to make it a string
- // static_cast<string>(var) doesn't cast to a string, so this is what I came up with
- digitAsString = digit;
- evenCount++;
- // If this is the first even digit encountered, add some explanatory text to the line
- if (evenCount == 1) evenDigits.append("Even digits: ");
- evenDigits.append(digitAsString);
- evenDigits.append(" ");
- }
- }
- }
- // If there are no even digits, use a literal output string
- if (evenCount == 0) evenDigits = "There are no even digits.";
- }
- void checkOddDigit(string fileData, string &oddDigits){
- unsigned long int fileDataLength = fileData.length();
- unsigned long int counter;
- unsigned long int oddCount = 0;
- unsigned short int digit;
- string digitAsString;
- for (counter = 0; counter < fileDataLength; counter++) {
- // Only try to get oddness if we're dealing with an actual integer
- if (isnumber(fileData[counter])) {
- digit = fileData[counter];
- // If a number is odd, add it to our string we'll eventually output
- if (digit % 2 == 1) {
- oddCount++;
- // You can't use string.append() with an integer, so we have to make it a string
- // static_cast<string>(var) doesn't cast to a string, so this is what I came up with
- digitAsString = digit;
- // If this is the first odd digit encountered, add some explanatory text to the line
- if (oddCount == 1) oddDigits.append("Odd digits: ");
- oddDigits.append(digitAsString);
- oddDigits.append(" ");
- }
- }
- }
- // If there are no odd digits, use a literal output string
- if (oddCount == 0) oddDigits = "There are no odd digits.";
- }
- void displayResults(string evenDigits, string oddDigits){
- cout << evenDigits << endl;
- cout << oddDigits << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement