Class to convert garbage to a number

  • Thread starter Thread starter Babsuranium
  • Start date Start date
  • Tags Tags
    Class Convert
AI Thread Summary
The discussion centers around a class named CIsDigit, designed to validate user input in console applications by determining if a given string contains valid numeric data. The class can handle various input sizes and ensures that the program does not crash when invalid characters are entered. It parses the input string to check for digits and decimals, writing valid numbers to a temporary file before reading them back into a double variable. The class provides several public functions for setting and retrieving values, as well as checking the validity of the input.The author emphasizes the importance of structuring code across multiple files rather than consolidating everything into one, and encourages users to credit them if they share the code. Additionally, an alternative method using the standard library function strtod is suggested for input validation, which can handle leading spaces but requires further logic to manage trailing spaces. The discussion highlights the need for effective input validation to prevent program errors and improve user experience.
Babsuranium
Messages
1
Reaction score
0
I wrote this class that works with a consol application. I'm sure you could add this to any other one of your programs like MFC applications. The way it works is takes in a whole string of garbage. any size, to an extent. this is not a string array. uses the include file <string>.
For example say you enter: alke2i lk2asdlkfj e
on most of my own programs and I am sure for you noobs it will crash your program if the text you need to read is a number, not chars and spaces...
this thing WILL NOT crash! (if you find a bug I am sorry, fix it and re post the fixed code)
Then it parses through the string and checks to see if the garbage is a valid digit or a decimal "."
if the garbage is valid it writes it to a file and then reads the files contents into a double. you can change the class to disallow decimal's or allow negative numbers...and change everything to ints if you don't have much memory. etc...
Let me know if you have an questions should my code be an utter mess and confusion. if you have no idea how to use classes may i suggest
http://newdata.box.sk/bx/c/htm/ch06.htm
the way i wrote it is in separate files... they teach it by putting everything in one .cpp file which works but its not structured etc etc etc...
The only file you need to make this beauty work is a driver file. your main program file. call it main.cpp driver.cpp or whatever.
Declare an instance of this class the class name is CIsDigit.
also you can include all your other include files in IsDigit.h. you don't need to add #include <iostream> or using namespace std in your driver.cpp file because its already in IsDigit.h file.
below is a bit of sample code how to make this bad boy work...
Code:
CIsDigit myNumber; // a possible name for a class in your driver.cpp file
string sDigit;
getline (cin, sDigit);
myNumber.SetDigit(sDigit); // sets the mess to the class member variable
myNumber.IsDigit();
// you need to declare these variables and use a loop or other such
//means to test the value of them. read the code below to figure out
//what each one does...
myNumber.GetTRUTH (bTRUTH, bOVERLOAD, bFileStream);
myNumber.GetValue(dValue);
// dValue will hold the value of the number entered by the user. btw its double not the "d" in "dValue"
something like this... if you can't figure it out you need to read that site
and one last thing... You can use the code by all means...but if you pass it on please give me the credit for wracking my brain out...
if there is any easyer way to do this my ears are clear of wax. I'm just frustrated at trying to figure out a simple yet very effective way to validate a users input. sick of getting the program to choke when i accidently type a char...
also i have a char validator. works almost the same way just instead of isdigit in the IsDigit.cpp file i used isalpha. there are all those is... functions that can be applied. with isalpha it would be even easyer because there would be no need to write it to a file and read the file...
Here's the code for IsDigit.h
Code:
// CLASS VALIDATOR WAS MADE BY ROBERT BABILON
// making sure IsDigit.h was not included more then once
#pragma once
// include files
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
using namespace std;
// this class will determine if a string is all digits
// or not. if so then it will find if there is a decimal
// and make a pointer to hold a float value or a pointer
// will be made for an int value
// class name
class CIsDigit
{
// PUBLIC FUNCTIONS
public:
// default constor and destructor
CIsDigit(void);
~CIsDigit(void);
// SetDigit sets input string to member variable
void SetDigit (string sDigit);
// GetDigit returns the member string
void GetDigit (string & sDigit) const;
// GetValue returns the digit value
void GetValue (double & dValue) const;
// GetTRUTH returns the truth values if string is digit or if too many digits after decimal
void GetTRUTH (bool & bTRUTH, bool & bOVERLOAD, bool & bFileStream) const;
// function to return truth value for status of deleting IsDigit.txt
void GetREMOVED (bool & bREMOVED) const;
//void GetFileStream (bool & bFileStream) const;
// function to find if string is a digit
void IsDigit (void);
// function to calculate the value of the digit
void CalcValue (void);
// function to delete temporary file
void DeleteTempFile(void);
// PRIVATE VARIABLES
private:
// string to be tested
string m_sDigit;
// truth variables
bool m_bTRUTH;
bool m_bDEC;
bool m_bOVERLOAD;
bool m_bREMOVED;
bool m_bFileStream;
// other member variables
int m_nSize;
int m_nDEC_PLACE;
double m_dValue;
};
Below is the cpp file. This does all the awasome work! Make sure you only include the .h file. NOT the .cpp files. (for the noobs)
Code:
// CLASS VALIDATOR WAS MADE BY ROBERT BABILON
// including IsDigit.h - contains variables
#include "IsDigit.h"
// CONSTRUCTOR
CIsDigit::CIsDigit(void)
{
// initialize variables to prevent bugs
m_nSize = 0;
m_dValue = 0;
m_nDEC_PLACE = 0;
m_bOVERLOAD = true;
m_bTRUTH = true;
m_bDEC = false;
}
// DESTRUCTOR
CIsDigit::~CIsDigit(void)
{
}
// SETS MEMBER STRING m_sDigit
void CIsDigit::SetDigit (string sDigit)
{
m_sDigit = sDigit;
}
// RETURNS m_sDigit STRING
void CIsDigit::GetDigit (string & sDigit) const
{
sDigit = m_sDigit;
}
// RETURNS THE NUMBER VALUE OF STRING
void CIsDigit::GetValue (double & dValue) const
{
dValue = m_dValue;
}
// RETURNS THE TRUTH VALUES FOR IF DIGIT AND IF TOO MANY #'s AFTER DECIMAL POINT
void CIsDigit::GetTRUTH (bool & bTRUTH, bool & bOVERLOAD, bool & bFileStream) const
{
bTRUTH = m_bTRUTH;
bOVERLOAD = m_bOVERLOAD;
bFileStream = m_bFileStream;
}
// CHECKS IF THE STRING HAS A VALID NUMBER
void CIsDigit::IsDigit(void)
{
// boolean values
m_bOVERLOAD = true;
m_bTRUTH = true;
m_bDEC = false;
m_bFileStream = true;
// decimal index location
m_nDEC_PLACE = 0;
// tracks how many decimal points are in string
int nNumDEC = 0;
// standard index variable
int nIndex = 0;
// checking to see if the user entered anything at all
if (m_sDigit[0] == '\0')
{
// data entered was INVALID
m_bTRUTH = false;
}
else
{
// while (END OF STRING is not reached and string is still a VALID digit) loop
while ( m_sDigit[nIndex] != '\0' && m_bTRUTH )
{
// checking to see if string at nIndex is a digit
if ( isdigit(m_sDigit[nIndex]) )
{				
++nIndex;
} // if m_sDigit at nIndex has an integer
/* comment out m_sDigit[nIndex] == '.' section to exclude decimal #'s */
// else if m_sDigit at nIndex contains a decimal
else if ( m_sDigit[nIndex] == '.' )
{
// storing the decimal's location
m_nDEC_PLACE = nIndex;
++nIndex;
// incrementing the num of decimals
++nNumDEC;
// there is a decimal in this string
m_bDEC = true;
// if more then 1 decimal, string is INVALID digit
if (nNumDEC == 2)
{
m_bTRUTH = false;
}
} // end else if there is a decimal
else
{
// INVALID data, string is invalid
m_bTRUTH = false;
m_bDEC = false;
}
} // end while loop checking if m_sDigit contains valid numbers or a single "."
// getting size of string for decimal overload checking
m_nSize = strlen(m_sDigit.c_str());
// if there was a decimal
if (m_bDEC)
{
// checking how many nums are after decimal place (no more then 6 allowed
// double only holds to 6 decimal places
if ( (m_nSize - m_nDEC_PLACE - 1) >= 7)
{
// decimal is OK
m_bOVERLOAD = false;
}
else
{
// decimal is INVALID
m_bOVERLOAD = true;
}
} // end if there was a decimal place
} // end else - user entered something
}
// CALCULATES (or) CONVERTS STRING TO A DOUBLE
void CIsDigit::CalcValue(void)
{
// opens an output stream and writes
// the entire string to the file
ofstream FileOut;
FileOut.open("IsDigit.txt");
// makes sure file is opened
if (!FileOut)
{
m_bFileStream = false;
}
else
{
// writes entire string to file
FileOut << m_sDigit;
// closes file
if (FileOut)
{
FileOut.close();
}
else
{
m_bFileStream = false;
}
}
// now opens input stream and reads
// files contents to a double
ifstream FileIn;
FileIn.open("IsDigit.txt");
// makes sure file is open
if (!FileOut)
{
m_bFileStream = false;
}
else
{
// reads files contents into double
FileIn >> m_dValue;
// closes file
if (FileOut)
{
FileOut.close();
}
else
{
m_bFileStream = false;
}
}
} // calculate the digit's value
// DELETE TEMP FILE
void CIsDigit::DeleteTempFile (void)
{
// initialize variable
m_bREMOVED = false;
// set integer value to something other then 0 and -1
int nRemoved = 100;
// nRemoved is 0 for success -1 for failer
nRemoved = remove ("IsDigit.txt");
// assign boolean values pertaining to status of file deletion
if (nRemoved == 0)
{
// file was deleted true value assigned
m_bREMOVED = true;
}
else
{
// file was not deleted false value
m_bREMOVED = false;
}
} // DeleteTempFile
// RETURN THE BOOLEAN VALUE STATUS OF DELETING TEMP FILE
void CIsDigit::GetREMOVED (bool & bREMOVED) const
{
bREMOVED = m_bREMOVED;
} // GetREMOVED
 
Last edited by a moderator:
Technology news on Phys.org
Thanks for sharing.
 
  • Like
Likes hmmm27
Thank you for the code!

But let me ask you a question... why not use str:strtod instead? It will return in the 2nd argument the pointer past the last character it converted (or the input parameter if couldn't convert anything). So we can just subtract the two pointers to see if all characters in the input were converted or not.

Code:
#include <iostream>
#include <string>

int main()
{
    std::string sDigit = "-123.567";
    const char * pstr = sDigit.c_str();
    char * pendstr;
    double val = std::strtod( pstr, &pendstr );
    if( pendstr-pstr != sDigit.length() )
      std::cout << "Invalid input!" << '\n';
    else
      std::cout << "Valid input: " << val << '\n';
}

Now, notice that this will accept " 123" (because it skips leading spaces), but it will say "123 " is invalid (as it doesn't skip trailing spaces). I didn't add the logic to skip trailing spaces as I didn't know if you wanted to make "123 " valid or invalid; if you want to accept "123 ", then it's easy to add that - a one liner regex should do it. If, on the other hand, you want to make " 123" invalid, then it's another easy change (just check if sDigit[0] is space.
 
Thread 'Is this public key encryption?'
I've tried to intuit public key encryption but never quite managed. But this seems to wrap it up in a bow. This seems to be a very elegant way of transmitting a message publicly that only the sender and receiver can decipher. Is this how PKE works? No, it cant be. In the above case, the requester knows the target's "secret" key - because they have his ID, and therefore knows his birthdate.
I tried a web search "the loss of programming ", and found an article saying that all aspects of writing, developing, and testing software programs will one day all be handled through artificial intelligence. One must wonder then, who is responsible. WHO is responsible for any problems, bugs, deficiencies, or whatever malfunctions which the programs make their users endure? Things may work wrong however the "wrong" happens. AI needs to fix the problems for the users. Any way to...

Similar threads

Replies
75
Views
6K
Replies
3
Views
2K
Replies
35
Views
4K
Replies
1
Views
2K
Replies
1
Views
3K
Replies
3
Views
4K
Replies
6
Views
3K
Back
Top