0

The objective of this program is to read a line of characters to count and identify the number of words in the line. It must identify how many of those words are of the format as dates of the form MMDDYY.

For example, if the user enters: "Four score and die captain ago"

The output should be the following.

Total number of words: 6

Number of valid dates: 0

If the user enters "Four 032356 team ironman seven 231290 ago"

The output should be

Total number of words: 7

Number of valid dates: 1

I'm having a problem implementing the function validateDate. Also I don't know whether or not my approach of the date validiation is correct. My sincerest apology if the code is a mess, I'm kinda learning the basics. Thanks in advance. Here's the code:

// #include "stdafx.h"

// This program demonstrates the use of dynamic variables

// Dean DeFino

#include <iostream>
#include <cctype>
#include <cstring>

using namespace std;

const int MAXNAME = 10;

//Function prototype
void processCstring(char *);
bool validateDate(char[], int);

int main()
{
    int pos;
    char *name = nullptr;

    int result;

    const int SIZE = 81;    // The maximum size of the C-string.
    char *cstring;          // To hold a C-string
    char goAgain;           // To hold Y or N

    cstring = new char[SIZE]; // Fill in code to allocate the character array pointed to by cstring

    name = new char[SIZE];    // Fill in code to allocate the character array pointed to by name

    cout << "Enter your last name with exactly 10 characters." << endl;
    cout << "If your name has < 10 characters, repeat last letter. " << endl;
    cout << "Blanks at the end do not count." << endl;

    for (pos = 0; pos < MAXNAME; pos++)
        cin >> *(name + pos);   // Fill in code to read a character into the name array
                                // WITHOUT USING a bracketed subscript
    cout << "Hi ";

    for (pos = 0; pos < MAXNAME; pos++)
        cout << *(name + pos);

    do
    {
        cin.ignore();
        // Get a C-string.
        cout << "\nEnter a C-string containing 80 or fewer characters:\n";
        cin.getline(cstring, SIZE);

        // Display the number of words in the C-string.
        cout << "\nThe number of words in the C-string:  ";
        processCstring(cstring);


        // Does the user want to do this again?
        cout << "Process another string? (Y or N) ";
        cin.get(goAgain);

        // Validate the input. If the user enter something diferent of y,Y or n,N
        //then ask again for an answer.
        while ((toupper(goAgain) != 'Y') && (toupper(goAgain) != 'N'))
        {
            cout << "Please enter Y or N: ";
            cin.get(goAgain);
        }

    } while (toupper(goAgain) == 'Y');


    // Fill in code to deallocate cstring and name (two steps each pointer)
    delete cstring;
    cstring = nullptr;
    delete name;
    name = nullptr;

    return 0;
}

//***************************************************
// Function processString                               *
// This function counts the number of words and the  *
// number of valid datres in a string passed into an str.   *
//***************************************************

void processCstring(char *cStrPtr)
{
    char *str = cStrPtr;
    int numWords = 0;
    int numDates = 0;
    int count = 0; // Variable para que el loop no sea infinito.

    //****WARNING
    //Do NOT RUN this while loop until you fixed.
    //This is  infinite loop
    while (*(str + count) != '\0')
    {
        if (isspace(*(str + count)))    //Complete the code to count the number of words.
            count++;                    //Skip any leading spaces
        else if (isalnum(*(str + count)) && isspace(*(str + count + 1)))
            numWords++;
        count++;

        (validateDate(str, strlen(str));
            cout << "h";

        //Now count the number of valid dates in the form MMDDAA
        //for example 040390 is a valid date, 230490 is not valid
        // 23jun90 is not valid.
        //Use the function validateDate (pass the word you found as
        //parameter) to validate if the word is a valid date

    }

    cout << "\nTotal number of words: " << numWords + 1 << endl;
    cout << "Number of valid dates: " << numDates << endl;
}


//***************************************************
// Function validateDate                               *
// This function validate if a word received as a parameter  *
// is a valid date.                                     *
//***************************************************bool 

validateDate(char myPass[], int size)
{
    bool answer = false;
    int i = 0; // Arreglar
​
    while (i < size && !answer)
    {
        /*Validar que sea un string de 6 chars
            Que el primer char1 < 2
            char1 + char2 <= 9
            char3 < 4
            char3 + char4 <= 11*/
​
        if (static_cast<int>(myPass[0]) < 2)
        {
            if (static_cast<int>(myPass[0]) + static_cast<int>(myPass[1]) <= 9)
            {
                if (static_cast<int>(myPass[2]) < 4)
                {
                    if (static_cast<int>(myPass[2]) + static_cast<int>(myPass[3]) <= 11)
                    {
                        answer = true;
                        i++;
                    }
                }

            }
        }
    }
    return answer;
}
Nacho
  • 1,104
  • 1
  • 13
  • 30

3 Answers3

0

The simplest way for me is using regular expressions for date validation. You can read more about them here Regular expressions in C: examples? and search the Inetnet for regexec

There is also a C++ way of doing this: http://www.cplusplus.com/reference/regex/

Community
  • 1
  • 1
GMichael
  • 2,726
  • 1
  • 20
  • 30
0

You approach to validateDate() doesn't look correct and too complicated.

I also not agree to suggestion to use regexp for this purposes, because it make the task more complicated.

My version would like:

// this method could be improved
int parseDD(const char * in) {
  if (not std::isdigit(in[0]) or not std::isdigit(in[1])) {
    return -1;
  }

  return (in[0] - '0') * 10 + (in[1] - '0');
}

bool validateDate(const char myPass[], int size) {
  if (size != 6) {
    return false;
  }

  static int daysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

  int mm = parseDD(myPass);
  int dd = parseDD(myPass+2);
  int yy = parseDD(myPass+4);

  if (yy < 0) {
    return false;
  }

  if (not (mm > 0 and mm <= 12)) {
    return false;
  }

  int days = daysInMonth[mm];

  bool leap = yy % 4 == 0;

  if (mm == 2 and leap) {
    days += 1; // 29 Feb                                                                                                                                                             
  }

  if (not (dd > 0 and dd <= days)) {
    return false;
  }

  return true;
}
Vadim Key
  • 1,242
  • 6
  • 15
0

Well guys I went with a different method. Thanks for the responses. Definitely knew I was doing something wrong with the static_cast.

(Here's the code)

#include <iostream>
#include <cctype>
#include <cstring>

using namespace std;

const int MAXNAME = 10;

//Function prototype
void processCstring(char *);
bool validateDate(char[], int);

int main()
{
    int pos;
    char *name = nullptr;

    int result;

    const int SIZE = 81;    // The maximum size of the C-string.
    char *cstring;          // To hold a C-string
    char goAgain;           // To hold Y or N

    cstring = new char[SIZE]; // Fill in code to allocate the character array pointed to by cstring

    name = new char[SIZE];    // Fill in code to allocate the character array pointed to by name


    cout << "Enter your last name with exactly 10 characters." << endl;
    cout << "If your name has < 10 characters, repeat last letter. " << endl;
    cout << "Blanks at the end do not count." << endl;

    for (pos = 0; pos < MAXNAME; pos++)
        cin >> *(name + pos);   // Fill in code to read a character into the name array
                                // WITHOUT USING a bracketed subscript
    cout << "Hi ";

    for (pos = 0; pos < MAXNAME; pos++)
        cout << *(name + pos);

    do
    {
        cin.ignore();
        // Get a C-string.
        cout << "\nEnter a C-string containing 80 or fewer characters:\n";
        cin.getline(cstring, SIZE);

        // Display the number of words in the C-string.
        cout << "\nThe number of words in the C-string:  ";
        processCstring(cstring);


        // Does the user want to do this again?
        cout << "Process another string? (Y or N) ";
        cin.get(goAgain);

        // Validate the input. If the user enter something diferent of y,Y or n,N
        //then ask again for an answer.
        while ((toupper(goAgain) != 'Y') && (toupper(goAgain) != 'N'))
        {
            cout << "Please enter Y or N: ";
            cin.get(goAgain);
        }

    } while (toupper(goAgain) == 'Y');


    // Fill in code to deallocate cstring and name (two steps each pointer)
    delete cstring;
    cstring = nullptr;
    delete name;
    name = nullptr;

    return 0;
}

//***************************************************
// Function processString                               *
// This function counts the number of words and the  *
// number of valid datres in a string passed into an str.   *
//***************************************************

void processCstring(char *cStrPtr)
{
    char *str = cStrPtr;
    int numWords = 0;
    int numDates = 0;
    int size = 0;
    bool started = false;

    //****WARNING
    //Do NOT RUN this while loop until you fixed.
    //This is  infinite loop

    while (*str != '\0')
    {
        if (started && isspace(*str))
        {
            if (validateDate(str - size, size))
            {
                numWords++;
                numDates++;
            }
            else
                numWords++;

            size = 0;
        }
        else if (!isspace(*str))
        {
            if (started)
                size++;
            else
                started = true;
        }
        str++;
    }
    if (size > 0)
    {
        if (validateDate(str - size, size))
            numDates++;
        else
            numWords++;
    }

    //numDates = validateDate(str, strlen(str)); Test de la variable

    cout << "\nTotal number of words: " << numWords << endl;
    cout << "Number of valid dates: " << numDates << endl;
}

//***************************************************
// Function validateDate                               *
// This function validate if a word received as a parameter  *
// is a valid date.                                     *
//***************************************************
bool validateDate(char myPass[], int size)
{
    bool answer = false;
    int i = 0;
    while (i<size && !answer)
    {
        if (i == 0)
        {
            if (myPass[i] == '0')
                i++;
            else if (myPass[i] == '1')
            {
                if (myPass[i + 1] != '0' && myPass[i + 1] != '1' && myPass[i + 1] != '2')
                    i = 7;
                else
                    i++;
            }
            else
                i = 7;
        }
        if (i == 1)
            i++;
        if (i == 2)
        {
            if (myPass[i] == '0' || myPass[i] == '2')
                i++;
            else if (myPass[i] == '3')
            {
                if (myPass[i + 1] != '0' && myPass[i + 1] != '1')
                    i = 7;
                else
                    i++;
            }
            else
                i++;
        }
        if (i == 3)
        {
            if (isdigit(myPass[i]))
                i++;
            else
                i = 7;
        }
        if (i == 4)
        {
            if (isdigit(myPass[i]))
                answer = true;
            else
                i = 7;
        }
    }
    return answer;
}