Counting Variable Names

I'm stuck with coming up how to create this program that lets you enter a sentence and then counts how many of the words it contained were by C++ approved variable names, and then outputs the amount.

What I mean by approved variable names is that when you declare a variable in C++, you can't name it "1name" or "ÅÄÖ", and this program should investigate if any of the words you've entered would've been valid variable names.

I've tried lots of things but the program either works incorrectly or does nothing at all. I wanted to be able to do this myself, but it feels like I won't ever be able to come up with a solution. I would be very grateful if someone could help me here. I can show you one of my failed solutions. I think the program gets stuck in a loop somewhere because nothing happens when I run it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;

int determiningApprovedVariableNames(string word){
    int n = word.size(), x=0, name = 0, counter = 0, p=0;
    bool firstletter = true;
    while(p<n){
        char c = word[p];
        if(firstletter == true && (c>='0'&&c<='9')){
            do{
                p++;
            }while(word[p-1]!=' ' && !(word[p]!=' '));
        }
        else{
            x++;
            if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9')){
                counter++;
                firstletter=false;
            }
            if(cin.peek()==' '){
                if(counter==x){
                    counter=0;
                    x=0;
                }
                p++;
                firstletter=true;
            }
        }
        p++;
    }
    return name;
}

int main(){
    string sentence;
    int answer;
    cout << "Enter a sentence: "; getline(cin, sentence);
    answer = determiningApprovedVariableNames(sentence);
    if(answer == 0)
        cout << "Your sentence contained no by C++ approved variable names!";
    else
        cout << "Your sentence contained " << answer << " by C++ approved variable name(s)!";
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
#include <iostream>
#include <sstream>
#include <regex>

int main()
{
    std::string sentence;
    std::cout << "Enter a sentence: "; 
    std::getline( std::cin, sentence ) ;

    // identifier ::= (letter|"_") (letter | digit | "_")*
    std::regex identifier( "^[a-zA-Z_][a-zA-Z0-9_]*$" ) ; 
    int count = 0 ;
    
    // check each white space delimited token in the sentence
    std::istringstream stm(sentence) ;
    std::string token ;
    while( stm >> token ) if( std::regex_match( token, identifier ) ) ++count ;

    std::cout << "there were " << count << " valid identifiers (or keywords)\n" ;
}
I can't run your solution :/ Or, whenever I press enter after entering a sentence some strange error message gets written.
Last edited on
It requires C++11, you're probably on a C++03 compiler.

Writing my solution:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
using namespace std;

inline bool isGoodIndex(const std::string& in, unsigned int ix)
{
    return (ix < in.length());
}

void SkipWhitespace(const std::string& in, unsigned int& lastindex)
{
    while(isGoodIndex(in,lastindex) && isspace(in[lastindex]))
    {
        ++lastindex;
    }
}

void SkipWord(const std::string& in, unsigned int& lastindex)
{
    while(isGoodIndex(in,lastindex) && !isspace(in[lastindex]))
    {
        ++lastindex;
    }
}

int main()
{
    cout << "Enter a sentence: ";
    string test;
    getline( cin, test );
    unsigned int ThisIndex = 0;
    unsigned int Words = 0;
    SkipWhitespace(test,ThisIndex);
    while(isGoodIndex(test,ThisIndex))
    {
        SkipWord(test,ThisIndex);
        ++Words;
        SkipWhitespace(test,ThisIndex);
    }
    
    cout << "Found " << Words << " words." << std::endl;
    return 0;
}


EDIT: Whoops, you're on a C++11 then.
I thought it was a compiler error.
Last edited on
C++98, or broken C++11 standard library (GNU), and you have boost:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
#include <iostream>
#include <sstream>
#include <boost/regex.hpp>

int main()
{
    std::string sentence;
    std::cout << "Enter a sentence: ";
    std::getline( std::cin, sentence ) ;

    // identifier ::= (letter|"_") (letter | digit | "_")*
    boost::regex identifier( "^[a-zA-Z_][a-zA-Z0-9_]*$" ) ;
    int count = 0 ;

    // check each white space delimited token in the sentence
    std::istringstream stm(sentence) ;
    std::string token ;
    while( stm >> token ) if( boost::regex_match( token, identifier ) ) ++count ;

    std::cout << "there were " << count << " valid identifiers (or keywords)\n" ;
}

Your solution doesn't work correctly either, I think you need to read my explanation of the problem again, it isn't supposed to find the amount of words.
Pure C++98:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <string>
#include <iostream>
#include <sstream>
#include <cctype>

inline bool alpha_or_us( char c ) { return std::isalpha(c) || c == '_' ; }
inline bool alnum_or_us( char c ) { return std::isalnum(c) || c == '_' ; }

bool is_valid_identifier( const std::string& str )
{
    if( str.empty() || !alpha_or_us( str[0] ) ) return false ;
    for( std::size_t i = 1 ; i < str.size() ; ++i ) 
        if( !alnum_or_us( str[i] ) ) return false ;

    return true ;
}

int main()
{
    std::string sentence;
    std::cout << "Enter a sentence: ";
    std::getline( std::cin, sentence ) ;

    int count = 0 ;

    // check each white space delimited token in the sentence
    std::istringstream stm(sentence) ;
    std::string token ;
    while( stm >> token ) if( is_valid_identifier(token) ) ++count ;

    std::cout << "there were " << count << " valid identifiers (or keywords)\n" ;
}
Topic archived. No new replies allowed.