How to find whether a string is guid in c++ - c++

How to find whether a string is guid in native c++? a code sample would help greatly

If you need to do it by hand (information from wikipedia):
Check the length (36, including hyphens)
Check that the hyphens are at the expected positions (9-14-19-24)
Check that all other characters are hexadecimal (isxdigit)

You could use a regex to see if it complies with GUID format.

Try the following code - could help.
_bstr_t sGuid( _T("guid to validate") );
GUID guid;
if( SUCCEEDED( ::CLSIDFromString( sGuid, &guid ) )
{
// Guid string is valid
}

Here's a faster, native C++ version without regular expressions or scanf()-like calls.
#include <cctype>
#include <string>
using namespace std;
bool isCanonicalUUID(const string &s) {
// Does it match the format 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'?
if (s.length() != 36) return false;
if (s[8] != '-' || s[13] != '-' ||
s[18] != '-' || s[23] != '-')
return false;
for (int i = 0; i < s.length(); i++) {
if (i == 8 || i == 13 || i == 18 || i == 23) continue;
if (isspace(s[i])) return false;
if (!isxdigit(s[i])) return true;
}
return true;
}
bool isMicrosoftUUID(const string &s) {
// Does it match the format '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'?
if (s.length() != 38) return false;
if (s[0] != '{' || s[37] != '}') return false;
if (s[10] != '-' || s[15] != '-' ||
s[20] != '-' || s[25] != '-')
return false;
for (int i = 1; i < s.length()-1; i++) {
if (i == 10 || i == 15 || i == 20 || i == 25) continue;
if (isspace(s[i])) return false;
if (!isxdigit(s[i])) return true;
}
return true;
}
bool isUUID(const string &s) {
return isCannonicalUUID(s) || isMicrosoftUUID(s);
}

This method leverages the scanf parser and works also in plain C:
#include <stdio.h>
#include <string.h>
int validateUUID(const char *candidate)
{
int tmp;
const char *s = candidate;
while (*s)
if (isspace(*s++))
return 0;
return s - candidate == 36
&& sscanf(candidate, "%4x%4x-%4x-%4x-%4x-%4x%4x%4x%c",
&tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp, &tmp) == 8;
}
Test with e.g.:
int main(int argc, char *argv[])
{
if (argc > 1)
puts(validateUUID(argv[1]) ? "OK" : "Invalid");
}

Here's a code example in case you still need one :P
#include <ctype.h>
using namespace std;
bool isUUID(string uuid)
{
/*
* Check if the provided uuid is valid.
* 1. The length of uuids should always be 36.
* 2. Hyphens are expected at positions {9, 14, 19, 24}.
* 3. The rest characters should be simple xdigits.
*/
int hyphens[4] = {9, 14, 19, 24};
if (uuid.length() != 36)
{
return false;//Oops. The lenth doesn't match.
}
for (int i = 0, counter = 0; i < 36; i ++)
{
char var = uuid[i];
if (i == hyphens[counter] - 1)// Check if a hyphen is expected here.
{
// Yep. We need a hyphen here.
if (var != '-')
{
return false;// Oops. The character is not a hyphen.
}
else
{
counter++;// Move on to the next expected hyphen position.
}
}
else
{
// Nope. The character here should be a simple xdigit
if (isxdigit(var) == false)
{
return false;// Oops. The current character is not a hyphen.
}
}
}
return true;// Seen'em all!
}

Related

String and character comparison

I am new to programming and I need to search any string to see if it includes only the letters a,b,c,d,e or f. The minute the program finds a letter that is not one of those the program should return false. Here is my function
bool is_favorite(string word){
int length = word.length(); // "word" is the string.
int index = 0;
while (index < length) {
if ((word[index] == 'a') || (word[index] == 'b') || (word[index] == 'c')||
(word[index] == 'd')|| (word[index] == 'e')|| (word[index] == 'f')) {
return true;
}
else {
return false;
}
index++;
}
}
Thank you very much for nay help! :)
The moment the return statement is encountered, the function is exited. This means that the moment any of the characters 'a', 'b', 'c', 'd', 'e', 'f' is encountered while iterating, due to the return statement the function will be exited immediately.
You can use std::string::find_first_not_of as shown below:
std::string input = "somearbitrarystring";
std::string validChars = "abcdef";
std::size_t found = input.find_first_not_of(validChars);
if(found != std::string::npos)
std::cout << "Found nonfavorite character " <<input[found]<<" at position "<<found<< std::endl;
else
{
std::cout<<"Only favorite characters found"<<std::endl;
}
If you unroll the loop by hand, you will spot the problem immediately:
if ((word[0] == 'a') || (word[0] == 'b') || (word[0] == 'c')||
(word[0] == 'd')|| (word[0] == 'e')|| (word[0] == 'f')) {
return true;
}
else {
return false;
}
if ((word[1] == 'a') || (word[1] == 'b') || (word[1] == 'c')||
(word[1] == 'd')|| (word[1] == 'e')|| (word[1] == 'f')) {
return true;
}
else {
return false;
}
//...
That is, the return value depends only on the first element.
"The minute the program finds a letter that is not one of those the program should return false" means
if ((word[0] != 'a') || (word[0] != 'b') || (word[0] != 'c')||
(word[0] != 'd')|| (word[0] != 'e')|| (word[0] != 'f')) {
return false;
}
if ((word[1] != 'a') || (word[1] != 'b') || (word[1] != 'c')||
(word[1] != 'd')|| (word[1] != 'e')|| (word[1] != 'f')) {
return false;
}
// ...
// After checking all the characters, you know what all them were in
// your desired set, so you can return unconditionally.
return true;
or, with a loop:
while (index < length) {
if ((word[index] != 'a') || (word[index] != 'b') || (word[index] != 'c')||
(word[index] != 'd')|| (word[index] != 'e')|| (word[index] != 'f')) {
return false;
}
index++;
}
return true;
bool is_favorite(string word){
return ( word.find_first_not_of( "abcdef" ) == std::string::npos );
}
It returns true if, and only if, there are only the characters 'a' through 'f' in the string. Any other character ends the search immediately.
And if you exchange string word with const string & word, your function will not have to create a copy of each word you pass to it, but work on a read-only reference to it, improving efficiency.
bool is_favorite(string word){
int length = word.length(); // "word" is the string.
int index = 0;
while (index < length) {
if (word[index] > 'f' || word[index] < 'a')
return false;
index++;
}
return true;
}
The return true is logically in the wrong place in your code.
Your version returns true as soon as it finds one letter that is a through f. It's premature to conclude that the whole string is valid at that point, because there may yet be an invalid character later in the string.
bool is_favorite(string word){
int length = word.length(); // "word" is the string.
int index = 0;
while (index < length) {
if ((word[index] == 'a') || (word[index] == 'b') || (word[index] == 'c')||
(word[index] == 'd')|| (word[index] == 'e')|| (word[index] == 'f')) {
return true; // This is premature.
}
else {
return false;
}
index++;
}
}
Minimal change that illustrates where the return true should be: after the loop. The return true is reached only if and only if we did not detect any invalid characters in the loop.
bool is_favorite(string word){
int length = word.length(); // "word" is the string.
int index = 0;
while (index < length) {
if ((word[index] == 'a') || (word[index] == 'b') || (word[index] == 'c')||
(word[index] == 'd')|| (word[index] == 'e')|| (word[index] == 'f')) {
// Do nothing here
}
else {
return false;
}
index++;
}
return true;
}
Obviously now that the affirmative block of the if is empty, you could refactor a little and only check for the negative condition. The logic of it should read closely to the way you described the problem in words:
"The minute the program finds a letter that is not one of those the program should return false."
bool is_favorite(string word){
int length = word.length(); // "word" is the string.
int index = 0;
while (index < length) {
if (!is_letter_a_through_f((word[index])
return false;
index++;
}
return true;
}
I replaced your large logical check against many characters with a function in the above code to make it more readable. I trust you do that without difficulty. My own preference is to keep statements short so that they are readable, and so that when you read the code, you can hold in your short-term memory the logic of what you are saying about control flow without being overloaded by the mechanics of your letter comparison.

Debug Assertion Failed in for

I got an error on second if
Making the exactly same if outside of for seems to work just fine, it returns the value from priority function, but when I try to do it in for it said that I'm trying to pass an invalid parameter to a function which considers it to be fatal.
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int priority(char c);
int main()
{
stack<char>Operator;
string input;
string output;
getline(cin, input);
for (int i = 0; i < input.size(); i++)
{
if (input[i] == '(' || input[i] == ')' || input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/')
Operator.push(input[i]);
else
output.push_back(input[i]);
if (priority(Operator.top()) == 3)
{
int aux = Operator.top();
Operator.pop();
while (priority(Operator.top() == 4))
{
output.push_back((char)Operator.top());
Operator.pop();
}
Operator.push(aux);
}
if (priority(Operator.top() == 2))
{
Operator.pop();
while (priority(Operator.top()) != 1)
{
output.push_back(Operator.top());
Operator.pop();
}
Operator.pop();
}
}
cout << output;
cin.ignore();
cin.get();
return 0;
}
int priority(char c)
{
if (c == '(')
return 1;
if (c == ')')
return 2;
if (c == '+' || c == '-')
return 3;
if (c == '*' || c == '/')
return 4;
}
The statement Operator.top() is being called on every symbol in the input string. That would probably work in case your string starts with a '(' symbol or with a unary plus, but what would happen in case of "2*2"?
As a perfect solution you should redesign your code to make it a finit automaton. As a simple ad hoc fix you should check if the current symbol is an operation or digit and don't call the Operator.top() in the latter case:
if (isdigit(input[i])) {
output.push_back(input[i]);
}
else {
Operator.push(input[i]);
if (priority(Operator.top()) == 3) {
// ...
}
// ...
}

English to Pig Latin in C++ using specific functions

Ok, so I'm working on a project that requires us to translate English to Pig Latin. I was trying to kind of copy and tweak some code I found online that did the opposite because the functions kind of looked similar. In my class, we are given certain functions that have to be implemented in our code.
This has to be present in my source code:
struct Word
{
string english;
string pigLatin;
};
Function 1: Word * splitSentence(const string words, int &size); ~ Takes the English sentence as 1 string
Function 2: void convertToPigLatin(Word [] wordArr, int size); ~ Converts English to Pig Latin
Function 3: void convertToPigLatin(Word [] wordArr, int size); ~ Display
Here is the code that I have.
Edit: The problem I'm having is that I don't have wordArr declared anywhere in my code so it can't compile. I also noticed a few minor errors and changed my code a little. You'll have to excuse me I'm very tired right now.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
struct Word
{
string english;
string pigLatin;
};
Word * splitSentence(wordArr&; int &);
void convertToPigLatin (Word[], int);
void displayPigLatin (Word[], int);
int main()
{
string userInput;
int size;
cout <<"This is an English to Pig Latin translator.\n";
cout <<"Enter a sentance that you want to translate.\n";
getline(cin, userInput);
Word *wordArr = convertToPigLatin(userInput, size);
displayPigLatin(wordArr, size);
return 0;
}
Word * splitSentence(const Word [] wordArr, int &size)
{
int num = 0;
int phraseLength = userInput.length();
for (int i = 0; i < size; i++)
{
if (isspace(userInput[i]))
{
if (isspace(userInput[ i - 1]))
{
num--;
}
num++;
}
}
if (ispunct(userInput[i]))
{
if (i != (phraseLength - 1))
{
userInput.erase(1--, 1)
}
}
}
void convertToPigLatin(Word wordArr[], int size)
{
for (int i = 0; i < size; i++)
{
int stringLength;
if (i == (size - 1))
{
stringLength = wordArr[i].userInput.length();
}
else
{
stringLength = wordArr[i].userInput.length() - 1;
}
string vowel, way;
vowel = wordArr[i].userInput.at(stringLength - stringLength);
way = wordArr[i].userInput.at(stringLength - 3);
bool markV = ((vowel == 'A') || (vowel == 'a') (vowel == 'E') || (vowel == 'e')
(vowel == 'I') || (vowel == 'i') (vowel == 'O') || (vowel == 'o')
(vowel == 'U') || (vowel == 'u'));
wordArr[i].userInput.erase(stringLength - 3, 3);
if (!(markV && (way == 'w')))
{
wordArr[i].english = way + wordArr[i].userInput;
}
}
displayPigLatin(wordArr, stringLength);
}
void displayPigLatin(const Word wordArr[], int size);
{
cout << "\nHere is your phrase in PigLatin: ";
for (int i = 0 i < size; i++)
{
cout << wordArr[i].userInput << " ";
}
}
Important Note: You can only use range based for-loops in C++11 or higher if your compiler doesn't support C++11 or higher, use regular for-loops...
Given your question, you have to use this structure (It is equivalent to the one in the question):
typedef struct
{
std::string english;
std::string pig_latin;
} Word;
This is a macro which is going to be used to check if the first letter is a vowel or a consonant (Hence, !IS_VOWEL(some_char))...
#define IS_VOWEL(x) ((x) == 'A' || (x) == 'E' || (x) == 'I' || (x) == 'O' || (x) == 'U' || \
(x) == 'a' || (x) == 'e' || (x) == 'i' || (x) == 'o' || (x) == 'u')
Another function which we need to acquire only the part of the word which has letters (not symbols and numbers):
std::pair<unsigned, unsigned> GetWord(std::string word)
{
auto start = word.end();
for (auto it = word.begin(); it != word.end(); ++it)
if (tolower(*it) >= 'a' && tolower(*it) <= 'z' && start == word.end())
start = it;
else if (start != word.end() && !(tolower(*it) >= 'a' && tolower(*it) <= 'z'))
return std::make_pair(std::distance(word.begin(), start), std::distance(word.begin(), it));
return std::make_pair(start == word.end() ? 0 : std::distance(word.begin(), start), std::distance(word.begin(), word.end()));
}
And last but not least, the function to convert English to Pig-Latin (I know it is huge):
std::vector<Word> CreatePigLatinWordsFromEnglish(std::string english, bool sentence_case = true)
{
// You can break it from here to use inside another function (viz., splitSentence)
std::transform(english.begin(), english.end(), english.begin(), ::tolower);
std::stringstream english_stream(english);
std::vector<Word> words;
std::string temporary;
while (std::getline(english_stream, temporary, ' '))
words.emplace_back(Word({ temporary, "" }));
// Till here...
// From here the conversion starts...
for (auto &word : words)
{
auto const word_it = GetWord(word.english);
if (!IS_VOWEL(word.english[word_it.first]) && !std::string(std::next(word.english.begin(), word_it.first),
std::next(word.english.begin(), word_it.second)).empty())
{
word.pig_latin.append(std::string(word.english.begin(), std::next(word.english.begin(), word_it.first)));
word.pig_latin.append(std::string(std::next(word.english.begin(), word_it.first + 1), std::next(word.english.begin(), word_it.second)));
word.pig_latin.append(1, word.english[word_it.first]);
word.pig_latin.append(std::string("ay"));
word.pig_latin.append(std::next(word.english.begin(), word_it.second), word.english.end());
}
else
word.pig_latin = std::string(word.english.begin(), std::next(word.english.begin(), word_it.second)) + "way"
+ std::string(std::next(word.english.begin(), word_it.second), word.english.end());
}
// Conversion ends here...
// Changing the case from lower case to sentence case if needed...
if (sentence_case)
{
words[0].english[0] = toupper(words[0].english[0]);
words[0].pig_latin[0] = toupper(words[0].pig_latin[0]);
}
return words; // Returning the list of words we got...
}
Well, an example to demonstrate this method:
int main()
{
auto const test = "An apple a day keeps the doctor away!";
for (auto word : CreatePigLatinWordsFromEnglish(test))
std::cout << word.pig_latin << " ";
return 0;
}
Output:
Anway appleway away ayday eepskay hetay octorday awayway!
Try it out and see whether it gives you the required result...
Kind regards,
Ruks.

Boolean Function to Check Validity of Expression Recursively?

I want to create a kind of parser of the form:
#include <iostream>
#include <string>
#include <sstream>
#include <cctype>
using namespace std;
bool isValid(istringstream& is)
{
char ch;
is.get(ch); //I know get(ch) is a good start but this is as for as I got :)
.......
....
}
int main()
{
string s;
while(getline(cin,s))
{
istringstream is(s);
cout<<(isValid(is)? "Expression OK" : "Not OK")<<endl;
}
}
A boolean function that returns TRUE if the sequence of char is of the form "5" or "(5+3)" or "((5+3)+6)" or "(((4+2)+1)+6)" ...etc and FALSE for any other case
Basically, an expression will be considered as valid if it is either a single digit or of the form "open parenthesis-single digit-plus sign-single digit-close parenthesis"
Valid Expression = single digit
and
Valid Expression = (Valid Expression + Valid Expression)
Given that there is no limit to the size of the above form (number of opening and closing parenthesis..etc.) I'd like to do that using recursion
Being the newbie that I am.. Thank you for any helpful input!
To do a recursive solution you're gonna want to read the string into a buffer first, then do something like this:
int expression(char* str) {
if (*str == '(') {
int e1 = expression(str + 1);
if (e1 == -1 || *(str + 1 + e) != '+') {
return -1;
}
int e2 = expression(str + 1 + e + 1);
if (e2 == -1 || *(str + 1 + e + 1 + e2) != ')') {
return -1;
}
return 1 + e1 + 1 + e2 + 1;
}
if (*str >= '0' || *str <= '9') {
return 1;
}
return -1;
}
bool isvalid(char* str) {
int e1 = expression(str);
if (e1 < 0) {
return false;
}
if (e1 == strlen(str)) {
return true;
}
if (*(str + e1) != '+') {
return false;
}
int e2 = expression(str + e1 + 1);
if (e2 < 0) {
return false;
}
return (e1 + 1 + e2 == strlen(str));
}
Basically, the expression function returns the length of the valid expression at it's argument. If it's argument begins with a parenthesis, it gets the length of the expression after that, verifies the plus after that, then verifies the closing parenthesis after the next expression. If the argument begins with a number, return 1. If something is messed up, return -1. Then using that function we can figure out whether or not the string is valid by some sums and the length of the string.
I haven't tested the function at all, but the only case this might fail in that I can think of would be excessive parenthesis: ((5)) for example.
An alternative to recursion could be some sort of lexical parsing such as this:
enum {
ExpectingLeftExpression,
ExpectingRightExpression,
ExpectingPlus,
ExpectingEnd,
} ParseState;
// returns true if str is valid
bool check(char* str) {
ParseState state = ExpectingLeftExpression;
do {
switch (state) {
case ExpectingLeftExpression:
if (*str == '(') {
} else if (*str >= '0' && *str <= '9') {
state = ExpectingPlus;
} else {
printf("Error: Expected left hand expression.");
return false;
}
break;
case ExpectingPlus:
if (*str == '+') {
state = ExpectingRightExpression;
} else {
printf("Error: Expected plus.");
return false;
}
break;
case ExpectingRightExpression:
if (*str == '(') {
state = ExpectingLeftExpression;
} else if (*str >= '0' && *str <= '9') {
state = ExpectingEnd;
} else {
printf("Error: Expected right hand expression.");
return false;
}
break;
}
} while (*(++str));
return true;
}
That function's not complete at all, but you should be able to see where it's going. I think the recursion works better in this case anyways.

how to find if a given string conforms to hex notation, eg. 0x34FF without regex?

In regex it would be 0x[0-9a-fA-F]+, but how to achieve it in pure c++ ?
You can use the built-in methods of std::string to check that the first portion of the string is the literal "0x" and that the remainder of the string contains only the allowed characters. Here is the equivalent to the regular expression given in the question:
bool is_hex_notation(std::string const& s)
{
return s.compare(0, 2, "0x") == 0
&& s.size() > 2
&& s.find_first_not_of("0123456789abcdefABCDEF", 2) == std::string::npos;
}
With C++11 you can do it easily:
std::string str = "FF22ABCD16ZZ";
if (std::all_of(str.begin(), str.end(), ::isxdigit)) {
std::cout << str << " contains only hexadecimal digits" << std::endl;
}
Call strtoul and check for an error.
Try the following
bool IsHex(const std::string& str) {
if (str.length < 3 || str[0] != '0') {
return false;
}
if (str[1] != 'x' && str[1] != 'X') {
return false;
}
for (size_t i = 2; i < str.length; i++) {
char current = str[i];
if (current >= '0' && current <= '9') {
continue;
}
if (current >= 'A' && current <= 'F') {
continue;
}
if (current >= 'a' && current <= 'f') {
continue;
}
return false;
}
return true;
}
You could use this instead strspn to check for valid base.
http://www.cplusplus.com/reference/cstring/strspn/
example below in C++ this method checks for any radix valid base from
binary-to-base32
/* strspn valid-number example */
#include<iostream>
#include<cstdlib>
#include<cstring>
#define BINARY_BASE 2 /*Defining binary base*/
#define OCTAL_BASE 8 /*Defining octal base*/
#define DECIMAL_BASE 10 /*Defining decimal base*/
#define HEXA_BASE 16 /*Defining hexa-decimal base*/
#define BASE32_BASE 32 /*Defining base32 base*/
bool isValidNumber4Base(const char* numStr,int base)
{
const char *validBinary = "01";
const char *validOctal = "01234567";
const char *validDecimal = "0123456789";
const char *validHex = "0123456789abcdefxABCDEFX";
const char *validBase32 = "0123456789abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUV";
const char *validNumber = NULL;
validNumber = (base == BINARY_BASE) ? validBinary : ((base == OCTAL_BASE) ? validOctal :
(base == DECIMAL_BASE) ? validDecimal : (base == HEXA_BASE) ? validHex : (base == BASE32_BASE) ? validBase32 : NULL);
if(validNumber == NULL)
{
std::cerr<<"Invalid base encountered"<<std::endl;
exit(EXIT_FAILURE);
}
return (!numStr[strspn(numStr,validNumber)]) ? true : false;
}
/*Test Method */
int main ()
{
char *hexa_str = "0xFF";
std::cout<<"Valid Hexa : "<<std::boolalpha<<isValidNumber4Base(hexa_str,HEXA_BASE)<<std::endl;
return 0;
}
You could use std::count_if to check if the count equals the size.
std::string_view v("0xa3");
bool correctPrefix = v.rfind("0x", 0) == 0 && v.length() > 2;
correctPrefix = correctPrefix ? std::count_if(v.begin() + 2,
v.end(),
::isxdigit) == v.length() - 2 : false;