Check if string contain only letters - c++

I have a trouble with a search through a string, if I enter a word with only letters, it's work as needs, I though, the code works, but when I add a number in work, the code work also, the question that, is possible to accept only if my var contains only letters, and if it will find a number or symbol, to go at begining of code?
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
label:
string var1 = "";
cout << "Enter a word: ";
cin >> var1;
for (int i = 0; i < var1.size (); i++)
{
int uppercaseCHar = toupper (var1[i]);
if (uppercaseCHar < 'A' || uppercaseCHar > 'Z')
{
goto endloop;
cout << endl;
} else
goto label;
cout << endl;
}
endloop:
cout << "Yout word contains only letters";
}
Output:
Enter a word: work
Enter a word: wro1
Enter a word: 123
Yout word contains only letters

Here is a solution that uses std::all_of:
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
int main()
{
bool isAllLetters = false;
do
{
std::string var1;
std::cout << "Enter a word: ";
std::cin >> var1;
// check if all characters are letters
isAllLetters = std::all_of(var1.begin(), var1.end(), [](char ch)
{ return std::isalpha(static_cast<unsigned char>(ch));});
if ( isAllLetters )
std::cout << "Your word contains only letters\n";
else
std::cout << "Your word contains stuff other than letters\n"
} while ( !isAllLetters );
}

Simple and efficient (C++17):
#include <algorithm>
#include <cctype>
#include <string_view>
bool all_of_alpha(std::string_view s)
{
return std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isalpha(c); });
}

Avoid using goto as it will complicate debugging code in larger program , here's another way :
int main()
{
while (true) {
bool flag = false; // to check for numeric entry
string var1; // not req to initialize
cout << "Enter a word (press exit to end): ";
cin >> var1;
for (int i = 0; i < var1.size(); i++)
{
int uppercaseCHar = toupper(var1[i]);
if (!std::isalpha(uppercaseCHar))
{
flag = true;
break;
}
}
if (var1.compare("exit") == 0) break;
if (flag) {
cout << "Your word contains number";
cout << endl;
}
else
{
cout << "Your word contains only alphabets";
cout << endl;
}
}
}

You can also use regular expressions which will simplify the code further.
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main () {
regex reg_obj("^[A-Z]+$");
string var;
start_label:
cout << "Enter a word: ";
getline(cin, var);
if(regex_match(var, reg_obj))
goto endlabel;
else goto start_label;
endlabel:
cout << "your word contains only letters\n";
return 0;
};

Allow me to offer a more modern idiomatic version and assuming you only care about detecting alphabetic characters in the ASCII character set.
#include <iostream>
#include <algorithm>
#include <string>
int main()
{
std::string a = "abcdefgh";
std::string b = "abcd3fgh";
std::string c = "abcdefg0";
auto is_alpha = [](unsigned char c){ return std::isalpha(c); };
bool aContainsAlphas = std::all_of(a.begin(), a.end(), is_alpha);
bool bContainsAlphas = std::all_of(b.begin(), b.end(), is_alpha);
bool cContainsAlphas = std::all_of(c.begin(), c.end(), is_alpha);
std::cout << std::boolalpha;
std::cout << "A: " << aContainsAlphas << '\n'; // true
std::cout << "B: " << bContainsAlphas << '\n'; // false
std::cout << "C: " << cContainsAlphas << '\n'; // false
}
This defines a lambda which is passed as an argument to std::all_of, which uses it to test each character:
auto is_alpha = [](unsigned char c){ return std::isalpha(c); };
This invokes is_alpha on each element between a.begin() and a.end(). If the end is reached without any mismatch for is_alpha, then true is returned.
bool aContainsAlphas = std::all_of(a.begin(), a.end(), is_alpha) != a.end();

Related

How can I count alphabet characters efficiently?

I initialized an array of characters, to put all uppercase and lowercase alphabets.
#include <iostream>
using namespace std;
int main () {
char c;
int cnt = 0;
cout << "Enter 0 to view the results " << endl;
char arr[52] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
while (1) {
for (int i = 0; i < 100000000; i++)
{
cin >> c;
if (c == arr[i]){
cnt++;
}
else if (c == '0'){
break;
}
else{
cout << "Please enter only characters!" << endl;
}
}
if (c == '0')
break;
}
cout << cnt << endl;
return 0;
}
I know that this code is inefficient.
How to write this code without break;?
If there's a better way to do that without using array, please mention it.
OP's question is very unclear but what I have understood from the comments is OP trying to find a simpler/similar way of counting someone's input for lowercase/upperCase alphabets and keep doing so until the user enters in a 0, I looked online and i found a better way and did some adjustments, it is pretty straight forward, here it is below.
#include <algorithm>
#include <iostream>
#include <cctype>
#include <string>
using namespace std;
int main()
{
string s = "TEST";
while(s != "0"){
cout << " Enter text: ";
getline(cin, s);
size_t count_alpha = count_if(s.begin(), s.end(),
[](unsigned char ch) { return isalpha(ch); });
cout << "Alphabets: " << ( count_alpha)<<endl ;
}
}

How do I write a function that counts consecutive letters in a string that are identical

searchingWrite a function conseclets which will receive one string as parameter. The function will determine all cases in which two or more consecutive letters in the string are identical.
For example, if "Barrymoore" is sent to the function, it will say that there are consecutive letters r and o in the string. But if "Bush" is sent to the function, it will say there are no two consecutive letters which are the same.
Here is my code the problem with it is when I put in a letter to find it finds it but not consecutively
#include <iostream>
#include <string>
using namespace std;
int main ()
{
char searching='\0';
string name=" ";
int counter =0;
cout<<"Enter a name : "<<endl;
getline(cin, name);
cout<<"Which letter would you like to count the number of times it appears: "<<endl;
cin>>name;
for(int i=0; i<name.length();i++){
if(sentence[i]==searching){
counter++;
}
}
cout<<"The letter " << searching << " appears "<< counter << " times ";
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main(int argc, char *argv[]) {
char a[30];
int i,c=0;
printf("enter a string\n");
gets(a);
for(i=0;i<strlen(a);i++)
{
if(a[i]==a[i+1])
{
printf("%c is consecutive\n",a[i]);
c++;
}
}
if(c==0)
{
printf("No consecutive letters");
}
return 0;
}
// Check this. This is proper code for your problem.
Here is an implementation making use of the standard algorithm library. I've called "runs" the sequences of identical consecutive letters. The algorithm is not necessarily optimal, but it's simple and that matters too.
void conseclets(std::string const &str) {
// Keep the end of the string, and point i to the first run's beginning
auto e = end(str), i = std::adjacent_find(begin(str), e);
if(i == e)
std::cout << "No repetition.\n";
else do {
// Locate the end of the run (that is, the first different letter)
auto next = std::find_if(i, e, [&i](auto const &c){ return c != *i; });
// Print out the match
std::cout << "Letter " << *i << " is repeated "
<< std::distance(i, next) << " times.\n";
// Skip to the next run's beginning
i = std::adjacent_find(next, e);
// Do so until we reached the end of the string
} while(i != e);
}
Live on Coliru
though there are several ways to do it, just modifying yours optimally to achieve whats required here :
#include <iostream>
using namespace std;
int main() {
cout << "Hello, World!" << endl;
char searching = '\0';
string name = " ";
int counter = 0;
cout << "Enter a name : " << endl;
getline(cin, name);
cout << "Which letter would you like to count the number of times it appears: " << endl;
cin >> searching;
for (int i = 0; i < name.length(); i++) {
if (name[i] == searching) {
counter++;
}
}
cout << "The letter " << searching << " appears " << counter << " times ";
return 0;
}
#include <iostream>
#include <iterator>
using namespace std;
template<typename I, typename O> O repeats(I b, I e, O result){
while(b!=e){
bool once = true;
I p = b;
while(++b!=e && *p==*b){
if(once){
*result++ = *p;
once = false;
}
}
}
return result;
}
int main() {
string name = "Barrymoore";
string res;
repeats(begin(name), end(name), back_inserter(res));
cout << "There are " << res.size() << " consecutive letters :" << res << endl;
return 0;
}

How to loop through a string using find() C++

The loop in the program seems to execute at least once, even if there are no occurences of the substring. Why is this?
#include <iostream>
#include <string>
using namespace std;
int countSubstrings(const string& original_string, const string& substr) {
int number_of_ocurrences = 0;
int i = 0;
for (i = original_string.find(original_string, 0); i != string::npos;
i = original_string.find(substr, i)) {
number_of_ocurrences++;
i++;
}
return number_of_ocurrences;
}
int main() {
string input;
while (1) {
cout << "Enter a a line of text: ";
getline(cin, input, '\n');
cout << '\n';
cout << "Number of ocurrences of the word needle: ";
cout << countSubstrings(input, "needle") << '\n';
}
}
Initially when you set i in your for loop you have
original_string.find(original_string, 0)
So you are searching the string for itself which it will find. I believe you meant to have
original_string.find(substr, 0)

beginner :While loop not working as it should

I am still a beginner and I am learning from a book. There was a drill that asked me filter input based on a vector of filtered words and if it was one of them it outputs "bad word"
Here is the drill exactly as in the book.
Try This
Write a program that “bleeps” out words that you don’t like; that is, you read in words using cin and print them again on cout. If a word is among a few you have defined, you write out BLEEP instead of that word. Start with one “disliked word” such as string disliked = “Broccoli”
When that works, add a few more.;
Here is the code I wrote:
#include <D:\std_lib_facilities.h>
int main()
{
// RL: omitting actual "bad" words to protect the innocent...
vector <string> bwords { "word1", "word2", "word3" };
vector <string> words;
string input = "";
while(cin >> input)
{
words.push_back(input);
}
double counter1 = 0;
double counter2 = 0;
while(counter1 < bwords.size() && counter2 < words.size())
{
if(bwords[counter1] == words[counter2])
{
cout << " bad word ";
}
else if (counter1 == bwords.size() - 1 && counter2 != words.size() )
{
cout << " "<< words[counter2] <<" ";
counter1 = 0;
}
else
{
++counter1;
counter2 += 1 / bwords.size();
}
}
}
whenever it starts it just tests the first word and repeats its self as if just tests the first if condition.
You over-complicated your loop. Try something more like this instead:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// RL: omitting actual "bad" words to protect the innocent...
const vector <string> bwords { "word1", "word2", "word3" };
string bleepWordIfBad(const string &word)
{
if (std::find(bwords.begin(), bwords.end(), word) != bwords.end())
return "BLEEP";
else
return word;
}
int main()
{
vector <string> words;
string input;
while (cin >> input)
words.push_back(input);
for (int counter = 0; counter < words.size(); ++counter)
cout << " " << bleepWordIfBad(words[counter]) << " ";
/*
Alternatively:
for (vector<string>::iterator iter = words.begin(); iter != words.end(); ++iter)
cout << " " << bleepWordIfBad(*iter) << " ";
*/
/*
Alternatively:
for (const string &word : words)
cout << " " << bleepWordIfBad(word) << " ";
*/
return 0;
}
Or, get rid of the manual loop altogether:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// RL: omitting actual "bad" words to protect the innocent...
const vector <string> bwords { "word1", "word2", "word3" };
string bleepWordIfBad(const string &word)
{
if (std::find(bwords.begin(), bwords.end(), word) != bwords.end())
return "BLEEP";
else
return word;
}
void outputWord(const string &word)
{
cout << " " << bleepWordIfBad(word) << " ";
}
int main()
{
vector <string> words;
string input;
while (cin >> input)
words.push_back(input);
for_each(words.begin(), words.end(), outputWord);
/*
Alternatively:
for_each(words.begin(), words.end(),
[](const string &word) { cout << " " << bleepWordIfBad(word) << " "; }
);
*/
return 0;
}
Or, get rid of the input vector altogether and just filter the user's input as it is being entered:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// RL: omitting actual "bad" words to protect the innocent...
const vector <string> bwords { "word1", "word2", "word3" };
string bleepWordIfBad(const string &word)
{
if (std::find(bwords.begin(), bwords.end(), word) != bwords.end())
return "BLEEP";
else
return word;
}
int main()
{
string word;
while (cin >> word)
cout << " " << bleepWordIfBad(word) << " ";
return 0;
}

i want to print every slot of my array at a new line

this is my current code , i have to print every world of my name on a new line
include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
int main ()
{
string a;
char j[100];
int i, c, b;
cout <<"enter your full name ";
getline(cin,a);
cout << " ur name is " << a << endl;
c=a.size();
for (b=0; b<=c; b++)
{
j[b]=a[b];
j[b]='\0';
}
system ("pause");
return 0;
}
how can i print every part of my name on a new line ? ex : input : geroge ashley mark . output : george (newline) ashley (newline) mark
This is a little convoluted way to do this, I prefer the method shown in the comments. However, if you want to avoid stringstreams, here is another way to achieve what you are looking for. It will also support comma separated names.
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
int main()
{
string a;
char j[100];
int i, c, b;
cout << "enter your full name ";
getline(cin, a);
cout << " ur name is " << a << endl;
c = a.size();
bool space = false;
for (auto iter = a.begin(); iter != a.end(); iter++)
{
if (isalpha(*iter) == false)
{
if (space == false)
{
cout << std::endl;
space = true;
}
}
else
{
cout << (*iter);
space = false;
}
}
system("pause");
return 0;
}