C++ Occurrence Task

Have this code given by instructor, instructor said it only needs 3-4 lines of code to do what it says and im confused what to do can anyone code it for me so I can see how to do it? I have to use the given code, so I have to find the best way to code it.
Instructions: Query the user for the name of a file and then count and
report the number of words that do not begin with the letter d, irrespective of case and the number of words that do begin with the letter d, irrespective of case.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
using namespace std;
int main (void)
{
    string inputFileName;
    string s;
    ifstream fileIn;
    int word_count;
    word_count=0;
    cout<<"Enter name of file of characters: ";
    cin>>inputFileName;
    fileIn.open(inputFileName.data());
    assert(fileIn.is_open());
    while (fileIn>>s)
    {
    word_count++;
    }
cout<<"Number of words in file: "<<word_count<<endl;
return 0;
}


and this code,

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
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <cstdio>
using namespace std;
int main(void)
{int i;
string inputFileName;
string s;
ifstream fileIn;
char ch;
cout<<"Enter name of file of characters :";
cin>>inputFileName;
fileIn.open(inputFileName.data() );
assert(fileIn.is_open() );
i=0;
while (!(fileIn.eof()))
    {ch=fileIn.get();
    s.insert(i,1,ch);
    i++;
    }
cout<<s<<endl;
cout<<"The length of n is "<<s.length()<<endl;
cout<<"The capacity of n is " <<s.capacity()<<endl;
cout<<"looking for string n "<<endl;
cout<<"found at position "<<s.find("n")<<endl;
return 0;
}
Last edited on
Also, when someone helps me out with this, I need to expand on it and not sure how to do it,
Same given code and here are instructions:
Query the user for the name of a file. Open and process that file, reporting the number of words
in the file and the number of words beginning with the letter d (irrespective of case) that have
one letter, the number of words having two letters, the number of words having three letters, and
so on.
You could begin with:

PLEASE learn to use code tags, they make reading and commenting on source code MUCH easier.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

HINT: you can edit your post and add code tags.

Some formatting & indentation would not hurt either
Do not start a new topic on the same subject, it's a time waster for those who reply. You were given good answers in the other topic.

https://www.cplusplus.com/forum/general/280239/
Last edited on
not the same way i need it a different way, its suppose to be 3 lines or 4 lines of code to add, they recoded the entire thing,.
I got it coded halfway, it works for letters D and d like the instructions say, I need it to now to count the number of words that are not D or d, how do I do that?
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <string>
#include <iostream>
#include <fstream>
#include <cassert>
#include <cstring>
using namespace std;

int main(void)
{
    int dCtr = 0,           //declare and initialize: dword counter
        wCtr = 0;           //and word counter
    string inputFileName;   //Declare variables
    string s;               //for storage
    ifstream fileIn;        //and file handling



// Introduce the program to the user

    cout << "This program will query the user for a file name.  The program will then open the file and count"<<endl;
    cout << "the words beginning with D or d, reporting the total count of words and the words beginning with "<< endl;
    cout << "d or D to the user.\n" << endl;

// query user for the name of a file

    cout << "Please enter the name of the file to open: ";
    cin >> inputFileName;

// open the file

    fileIn.open(inputFileName.data());

// check to see if file is successfully opened

    assert(fileIn.is_open() );
    cout<<"\nFile "<<inputFileName<<" successfully opened.\n"<<endl;

// read file in to string

    while((fileIn.good()))
    {

                fileIn >> s;
                if(fileIn.eof()) break;

                wCtr++;

//check to see if word begins with an alphabetical character, if so, check to see if the first character is d or D

            if(isalpha(s[0]))
            {
            if((s[0]=='d') || (s[0]=='D'))
                {
                dCtr++;
                }
            }

//if first character is not alpha, check to see if 2nd character begins with D or d

            else if((s[1]=='d') || (s[1]=='D'))
                {
                    dCtr++;
                }

    }
    cout<<"\nThere are a total of "<< wCtr <<" words."<<endl;
    cout<<"\nThere are "<<dCtr<<" words beginning with D or d."<<endl;
    return 0;
}
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
44
#include <string>
#include <iostream>
#include <fstream>
#include <cctype>

int main()
{
    std::string file_name;

    std::cout << "enter input file name: " ;
    std::cin >> file_name ;

    if( std::ifstream file{file_name} ) // if the file is opened for input
    {
        long long num_total_words = 0 ;
        long long num_dee_words = 0 ;
        std::string word ;

        // idiomatic C++ input loop: https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool
        while( file >> word ) // for each 'word' read from the file
        {
            ++num_total_words ;

            // check the first alpha character in the word
            // https://www.stroustrup.com/C++11FAQ.html#for
            for( unsigned char c : word ) // for each character in the word
                                          // unsigned char: required for safe use of std::isalpha
                                          // https://en.cppreference.com/w/cpp/string/byte/isalpha#Notes
            {
                if( std::isalpha(c) )
                {
                    if( c == 'D' || c == 'd' ) ++num_dee_words ; // first alpha character is 'd' or 'D'
                    break ; // we have got the first alpha char; so break out of the loop
                }
            }
        }

        std::cout << "total words in file: " << num_total_words << '\n'
                  << "words beginning with D or d: " << num_dee_words << '\n'
                  << "words not beginning with D or d: " << num_total_words-num_dee_words << '\n' ;
    }

    else std::cout << "failed to open input file\n" ;
}
Ok. Using the given code then:

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
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
using namespace std;

int main(void)
{
	string inputFileName, s;
	ifstream fileIn;
	int word_count = 0, dCount = 0;

	cout << "Enter name of file of characters: ";
	cin >> inputFileName;

	fileIn.open(inputFileName.data());
	assert(fileIn.is_open());

	while (fileIn >> s) {
		word_count++;
		dCount += s[0] == 'd' || s[0] == 'D';
	}

	cout << "Number of words starting with d or D is " << dCount << endl;
	cout << "Number of words not starting with d or D is: " << word_count - dCount << endl;
}

Last edited on
Nice code, but our professor wants it to use toupper I believe how can we make it that way? Is there anyway we can make it work with s.find, s.capacity, or s.length, to count for the starting occurrences of D or D, and for the time d doesn't occur as the starting occurrence? If not is there a way to make it with switch/case statements, trying to improve my code if you can show me how to do it It would be much appreciated.
sure, you can use toupper etc.

1
2
3
4
5
6
7
   if(isalpha(s[0]))
            {
            if((s[0]=='d') || (s[0]=='D'))
                {
                dCtr++;
                }
            }


lets preach on this chunk.
d and D are alpha. isalpha is useless.
d and D can make use of toupper if you like that.
booleans are 0 or 1, as integers. you don't have to check the boolean THEN count it. Conditions cost as much as simple math down in the CPU, so bypass doing twice the work:

put all that together, and you get this one liner:

dCtr += (toupper(s[0])== 'D'); //adding 0 when the condition fails costs less than checking 2 conditions...

the right side of that is line 3 of your snippet above.
Last edited on
OK L21:

 
dCount += static_cast<char>(std::toupper(static_cast<unsigned char>(s[0]))) == 'D';

Topic archived. No new replies allowed.