booleans with constraints - c++

How do I write a boolean that checks if a string has only letters, numbers and an underscore?

Assuming String supports iterators, use all_of:
using std::begin;
using std::end;
return std::all_of(begin(String), end(String),
[](char c) { return isalnum(c) || c == '_'; });

In an easier way, run a loop and check all the characters holding the property you mentioned, and if not, just return false.
Code:
bool stringHasOnlyLettersNumbsandUndrscore(std::string const& str)
{
for(int i = 0; i < str.length(); ++i)
{
//Your character in the string does not fulfill the property.
if (!isalnum(str[i]) && str[i] != '_')
{
return false;
}
}
//The whole string fulfills the condition.
return true;
}

bool stringHasOnlyLettersNumbsandUndrscore(std::string const& str)
{
return ( std::all_of(str.begin(), str.end(),
[](char c) { return isalnum(c) || c == '_'; }) &&
(std::count_if(str.begin(), str.end(),
[](char c) { return (c == '_'); }) < 2));
}

Check if each character is a letter, number or underscore.
for c and c++ , this should do.
if(!isalnum(a[i]) && a[i]!='_')
cout<<"No";
You will have to add < ctype > for this code to work.
This is just the quickest way that comes to mind, there might be other more complex and faster ways.

Related

Is this good enough to check an ascii string?

bool is_ascii(const string &word) {
if((unsigned char)(*word.c_str()) < 128){
return true
}
return false
}
I want to check whether a string is ascii string. I also saw such a function to detect whether a string is ascii chars or not:
bool is_ascii(const string &str){
std::locale loc;
for(size_t i = 0; i < str.size(); i++)
if( !isalpha(str[i], loc) && !isspace(str[i], loc))
return false;
return true;
}
Which one is better or more reliable?
Other answers get the is-char-ASCII part already. I’m assuming it’s right. Putting it together I’d recommend:
#include <algorithm>
bool is_ascii_char(unsigned char c) {
return (c & 0x80) == 0;
}
bool is_ascii(std::string_view s) {
return std::ranges::all_of(s, is_ascii_char);
}
https://godbolt.org/z/nKb673vaM
Or before C++20, that could be return std::all_of(s.begin(), s.end(), is_ascii_char);.
ASCII is a lot more than just alpha characters and spaces. If you want to accept all ASCII, just use your second example and change the if:
if(str[i] < 0 || str[i] > 0x7f)
return false;

Determine If String Has All Same Character

Is there a function like find_first_not_of that returns true or false as opposed to a position? I do not need the position, but rather whether or not the string contains all of the same char.
You could write your own function:
bool all_chars_same(string testStr) {
char letter = testStr[0];
for (int i = 1; i < testStr.length(); i++) {
if (testStr[i] != letter)
return false;
}
return true;
}
Or use the built in find_first_not_of:
bool all_chars_same(string testStr) {
return testStr.find_first_not_of(testStr[0]) == string::npos;
}
Just check the value returned by find_first_not_of for string::npos:
// needs to check if str.size() > 0
bool all_same = str.find_first_not_of(str[0]) == string::npos;
Alternatively, since you're looking for a single character, there's also std::all_of.
bool all_same = std::all_of(str.cbegin(), str.cend(), [&](char c){ return str[0] == c; });
use yourstring.find(keyword);
you can get detail here
http://www.cplusplus.com/reference/string/string/find/
I would recomend a define, it is the faster way.
#define find_not_of(a) (a.find_first_not_of(a[0]) != std::string::npos)
The best way and the quickest i can of is create a map and put the first value of the string as the key of the map. then iterate through the string and once you find one characters that is not in the map , you are done
bool allSameCharacters ( string s){
unordered_map < char , int> m;
// m.reserve(s.size());
m[s[0]]++;
for (char c : s ){
if (m.find(c) == m.end()) return false;
}
return true;
}

Is there an alternative to using str.substr( ) to extract a substring at a given position?

I am trying to compare two std::strings, and decide if string A is the same as string B, but with the insertion or deletion of a single character.
Otherwise it returns false.
For example: "start" and "strt" or "ad" and "add"
Currently:
if(((sizeA - sizeB) != 1)
&& ((sizeB - sizeA) != 1))
{
return false;
}
if(sizeA < sizeB)
{
for(int i = 0; i < sizeA; ++i)
{
if(stringA[i] != stringB[i])
{
if(stringA.substr(i)
== stringB.substr(i + 1))
{
return true;
}
else return false;
}
}
} //with another loop that runs only if stringA is larger than stringB
This works flawlessly, but gprof tells me that this function is being bogged down.
I tried converting the for loop to use iterators to access the chars, but this doubled my run time.
Ive narrowed it down to my use of std::string.substr( ) because it is constructing new strings each time stringA and stringB differ in size by 1.
When the first character differs, I need a more efficient way to check if I were to delete that character, would the two strings then be equal?
It seems, once it is known whether there is a one character difference the comparison can be done more effective with a single pass over the string: find the location of the difference, skip the character, and see if the tail is the same. To that end it is obviously necessary to know which one is the smaller string but that's trivial to determine:
bool oneCharDiff(std::string const& shorter, std::string const& longer) {
if (shorter.size() + 1u != longer.size() {
return false;
}
typedef std::string::const_iterator const_iterator;
std::pair<const_iterator, const_iterator> p
= std::mismatch(shorter.begin(), shorter.end(), longer.begin());
return std::equal(p.first, shorter.end(), p.second + 1);
}
bool atMostOneCharDiff(std::string const& s0, std::string const& s1) {
if (s0.size() < s1.size()) {
return oneCharDiff(s0, s1);
else if (s1.size() < s0.size()) {
return oneCharDiff(s1, s0);
}
else {
return s0 == s1;
}
}
Try:
if (stringA.compare(i, stringA.npos, stringB, i+1, stringB.npos) == 0) {
/* the strings are equal */
}
In this write-up, that's version (3) of std::basic_string::compare.
If your compiler supports it it may be worth checking out the new ISO/IEC TS 19568:xxxx Technical Specification string_view class.
It provides an immutable view of a string through references without copying the string itself so it promises to be much more efficient when dealing with substrings.
#include <experimental/string_view>
using std::experimental::string_view;
bool func(string_view svA, string_view svB)
{
// ... stuff
if(svA.size() < svB.size())
{
for(int i = 0; i < svA.size(); ++i)
{
if(svA[i] != svB[i])
{
if(svA.substr(i)
== svB.substr(i + 1))
{
return true;
}
else return false;
}
}
}
// ... stuff
return false;
}
As you can see it works pretty much like a drop-in replacement for std::string (or const char* etc...). Simply pass your normal std::string objects as arguments to the function and the string_view parameters will initialize from the passed in strings.

c++ char comparison to see if a string is fits our needs

i want to do my work if chars of the string variable tablolar does not contain any char but small letters between a-z and ','. what do you suggest?
if string tablolar is;
"tablo"->it is ok
"tablo,tablobir,tabloiki,tablouc"->it is ok
"ta"->it is ok
but if it is;
"tablo2"->not ok
"ta546465"->not ok
"Tablo"->not ok
"tablo,234,tablobir"->not ok
"tablo^%&!)=(,tablouc"-> not ok
what i tried was wrog;
for(int z=0;z<tablolar.size();z++){
if ((tablolar[z] == ',') || (tablolar[z] >= 'a' && tablolar[z] <= 'z'))
{//do your work here}}
tablolar.find_first_not_of("abcdefghijknmopqrstuvwxyz,") will return the position of the first invalid character, or std::string::npos if the string is OK.
bool fitsOurNeeds(const std::string &tablolar) {
for (int z=0; z < tablolar.size(); z++)
if (!((tablolar[z] == ',') || (tablolar[z] >= 'a' && tablolar[z] <= 'z')))
return false;
return true;
}
The c function islower tests for lowercase. So you probably want something along these lines:
#include <algorithm>
#include <cctype> // for islower
bool fitsOurNeeds(std::string const& tabular)
{
return std::all_of(tabular.begin(), tabular.end(),
[](char ch)
{
return islower(ch) || ch == ',';
});
}

Determine if a string contains only alphanumeric characters (or a space)

I am writing a function that determines whether a string contains only alphanumeric characters and spaces. I am effectively testing whether it matches the regular expression ^[[:alnum:] ]+$ but without using regular expressions. This is what I have so far:
#include <algorithm>
static inline bool is_not_alnum_space(char c)
{
return !(isalpha(c) || isdigit(c) || (c == ' '));
}
bool string_is_valid(const std::string &str)
{
return find_if(str.begin(), str.end(), is_not_alnum_space) == str.end();
}
Is there a better solution, or a “more C++” way to do this?
Looks good to me, but you can use isalnum(c) instead of isalpha and isdigit.
And looking forward to C++0x, you'll be able to use lambda functions (you can try this out with gcc 4.5 or VS2010):
bool string_is_valid(const std::string &str)
{
return find_if(str.begin(), str.end(),
[](char c) { return !(isalnum(c) || (c == ' ')); }) == str.end();
}
You can also do this with binders so you can drop the helper function. I'd recommend Boost Binders as they are much easier to use then the standard library binders:
bool string_is_valid(const std::string &str)
{
return find_if(str.begin(), str.end(),
!boost::bind(isalnum, _1) || boost::bind(std::not_equal_to<char>, _1, ' ')) == str.end();
}
Minor points, but if you want is_not_alnum_space() to be a helper function that is only visible in that particular compilation unit, you should put it in an anonymous namespace instead of making it static:
namespace {
bool is_not_alnum_space(char c)
{
return !(isalpha(c) || isdigit(c) || (c == ' '));
}
}
...etc
In case dont want to use stl function then this can be used:
// function for checking char is alphnumeric
bool checkAlphaNumeric(char s){
if(((s - 'a' >= 0) && (s - 'a' < 26)) ||((s - 'A' >= 0) && (s - 'A' < 26)) || ((s- '0' >= 0) &&(s - '0' < 10)))
return true;
return false;
}
//main
String s = "ab cd : 456";
for(int i = 0; i < s.length(); i++){
if(!checkAlphaNumeric(s[i])) return false;
}