text file statistics help

Pages: 12
This is a homework assignment and I am stuck and would appreciate any pointers or help on this. I have to write a code that will allow the user to type in the text file they want to open and then the will output the entire contents of the text file plus say how many uppercase letters, lowercase letters, punctuations and white spaces. If the file could not be opened then output an error message and exit. I am suppose to be using this for the loop
1
2
3
4
for (char c = file.get(); c != EOF; c = file.get())
{
     //The variable "c" now contains the next character from the file
} 


The problem I am having is that I do not know how to let the user type in the text file. I only know how to program that actual text file into the code. The other problem is that I am not sure how to output the entire contents of the text file either. The last problem I have is that I wrote this code and individually everything worked but when I put it all together the output is blank with nothing on it. Any help would be greatly apprecaited. Here is my code so far

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

int main()
{
    fstream data_store;
    char line[100];
    int i;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    data_store.open("hello.txt", ios::in);

    while (!data_store.eof())
    {
        data_store.getline(line, 100);
        for (int x = 0; x < strlen(line); x++)
        {
            char c = line[x];
            if (isalpha(c))
            {
                alpha_count++;
            }
            else if (ispunct(c))
            {
                punct_count++;
            }
            else if (isspace(c))
            {
                space_count++;
            }
            if ((line[i] >= 'a' && line[i] <= 'z'))
            {
                lower_count++;
                i++;
            }
            else if ((line[i] >= 'A' && line[i] <= 'Z'))
            {
                upper_count++;
                i++;
            }

        }

    }
    data_store.close();

    cout << "-- File contents --" << endl;

    cout << "-- End --" << endl;
    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}
Last edited on
You're not even using this code:
1
2
3
4
for (char c = file.get(); c != EOF; c = file.get())
{
     //The variable "c" now contains the next character from the file
} 


That will solve a lot of your issues to begin with.

Secondly, you pass a string to open a file. Why can't you have a user enter the string to open the file?
1
2
3
4
string fileName;
cout << "Please enter the filename: ";
cin >> fileName;
data_store.open(fileName, ios::in);


Don't forget to add the string header file.

If you just kept to using what your teacher told you to use, it's very simple, the instructions even say that variable "c" contains the next character in the file so you could print that out, do some cctype tests on it, and make your life much simpler.
When I changed the code I get this error
"line 28 error: 'struct std::string' has no member named 'get'" I didn't use the for loop from the instructor because I didn't understand how it worked and the ones I had all worked individually. Here is the code now.

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

int main()
{
    fstream data_store;
    char line[100];
    int i;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    string filename;
    string file;

    cout << "Enter a file name" << endl;
    cin >> filename;

    data_store.open(filename, ios::in);

    while (!data_store.eof())
    {
        data_store.getline(line, 100);
        for (char c = file.get(filename); c !=EOF; c = file.get (filename))
        {
            if (isalpha(c))
            {
                alpha_count++;
            }
            else if (ispunct(c))
            {
                punct_count++;
            }
            else if (isspace(c))
            {
                space_count++;
            }
            if ((line[i] >= 'a' && line[i] <= 'z'))
            {
                lower_count++;
                i++;
            }
            else if ((line[i] >= 'A' && line[i] <= 'Z'))
            {
                upper_count++;
                i++;
            }
        }
    }
    data_store.close();

    cout << "-- File contents --" << endl;
    cout << filename << endl;
    cout << "-- End --" << endl;
    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}
Last edited on
Because strings don't have a member function called get, fstreams do however, and you only have one fstream object, data_store. Also, the for loop is meant to replace your while loop, so remove the while loop and the data_store.getline(...);
I'm sorry, I'm still not sure what to do about the fstream function but either way when I changed the code I get a new error
"line 25 error: no matching function for calls to 'std::basic_fstream<char,
std::char_traits<char> ......" It keeps going but I can't see it all in my window.

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

int main()
{
    fstream data_store;
    char line[100];
    int i;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    string filename;
    string file;

    cout << "Enter a file name" << endl;
    cin >> filename;

    data_store.open(filename, ios::in);

        for (char c = file.get(filename); c !=EOF; c = file.get (filename))
        {
            if (isalpha(c))
            {
                alpha_count++;
            }
            else if (ispunct(c))
            {
                punct_count++;
            }
            else if (isspace(c))
            {
                space_count++;
            }
            else if ((line[i] >= 'a' && line[i] <= 'z'))
            {
                lower_count++;
                i++;
            }
            else if ((line[i] >= 'A' && line[i] <= 'Z'))
            {
                upper_count++;
                i++;
            }
    }
    data_store.close();

    cout << "-- File contents --" << endl;
    cout << filename << endl;
    cout << "-- End --" << endl;
    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}
Change line 9 and 23 from data_store to file and remove line 18
I made those changes and I also noticed that I am not using line 10 or atleast I don't think I am so I removed it as well. I still get the same error
"line 22 & 24 error: no matching function for call to 'std::basic_fstream<char, std::char_traits<char> >::get(char [100])'|"

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

int main()
{
    fstream file;
    char line[100];
    int i;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    string filename;

    cout << "Enter a file name" << endl;
    cin >> filename;

    file.open(filename, ios::in);

        for (char c = file.get(filename); c !=EOF; c = file.get(filename))
        {
            if (isalpha(c))
            {
                alpha_count++;
            }
            else if (ispunct(c))
            {
                punct_count++;
            }
            else if (isspace(c))
            {
                space_count++;
            }
            else if ((file >= 'a' && file <= 'z'))
            {
                lower_count++;
                i++;
            }
            else if ((file >= 'A' && file <= 'Z'))
            {
                upper_count++;
                i++;
            }
    }
    file.close();

    cout << "-- File contents --" << endl;
    cout << filename << endl;
    cout << "-- End --" << endl;
    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}
Don't use cstring, use string. cstring uses a character string that's not terminated by a null character, '\0', while string uses a null terminated string. This should allow it to be used in the file stream operator, should being the keyword. If you're required to use cstring, I believe there is a c_str() function somewhere, but I can't remember if you need another header file or not.
I changed cstring to string and I get the same error message. I found out how to copy the error messages so here is the code and all the messages that I get.

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

int main()
{
    fstream file;
    int i;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    string filename;

    cout << "Enter a file name" << endl;
    cin >> filename;

    file.open(filename, ios::in);

        for (char c = file.get(filename); c !=EOF; c = file.get(filename))
        {
            if (isalpha(c))
            {
                alpha_count++;
            }
            else if (ispunct(c))
            {
                punct_count++;
            }
            else if (isspace(c))
            {
                space_count++;
            }
            else if ((file >= 'a' && file <= 'z'))
            {
                lower_count++;
                i++;
            }
            else if ((file >= 'A' && file <= 'Z'))
            {
                upper_count++;
                i++;
            }
    }
    file.close();

    cout << "-- File contents --" << endl;
    cout << filename << endl;
    cout << "-- End --" << endl;
    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}



|21|error: no matching function for call to 'std::basic_fstream<char, std::char_traits<char> >::open(std::string&, const std::_Ios_Openmode&)'|

note: candidates are: void std::basic_fstream<_CharT, _Traits>::open(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]|

|23|error: no matching function for call to 'std::basic_fstream<char, std::char_traits<char> >::get(std::string&)'|

note: candidates are: typename std::basic_istream<_CharT, _Traits>::int_type std::basic_istream<_CharT, _Traits>::get() [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(_CharT&) [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(_CharT*, std::streamsize, _CharT) [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(_CharT*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(std::basic_streambuf<_CharT, _Traits>&, _CharT) [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]|

|23|error: no matching function for call to 'std::basic_fstream<char, std::char_traits<char> >::get(std::string&)'|

note: candidates are: typename std::basic_istream<_CharT, _Traits>::int_type std::basic_istream<_CharT, _Traits>::get() [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(_CharT&) [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(_CharT*, std::streamsize, _CharT) [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(_CharT*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(std::basic_streambuf<_CharT, _Traits>&, _CharT) [with _CharT = char, _Traits = std::char_traits<char>]|

note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::get(std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]|
||=== Build finished: 3 errors, 0 warnings ===|
Last edited on
Errors 2 and 3 can be solved by removing "filename" from lines 23.

Error 1 I believe I was wrong about the cstring issue. But I thought I was right. Anyways, to solve it, append .c_str() to filename on line 22.
OK, that solved those errors but now I have new errors. I think thses ones will be pretty simple. I can never remember which symbol goes first the = or <, > but when I switch them I get a new error. Here are the errors and the 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
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
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
using namespace std;

int main()
{
    fstream file;
    int i;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    string filename;
    string str();

    cout << "Enter a file name" << endl;
    cin >> filename;

    file.open(filename.c_str(), ios::in);

        for (char c = file.get(); c !=EOF; c = file.get())
        {
            if (isalpha(c))
            {
                alpha_count++;
            }
            else if (ispunct(c))
            {
                punct_count++;
            }
            else if (isspace(c))
            {
                space_count++;
            }
            else if ((file => 'a' && file =< 'z'))
            {
                lower_count++;
                i++;
            }
            else if ((file >= 'A' && file <= 'Z'))
            {
                upper_count++;
                i++;
            }
    }
    file.close();

    cout << "-- File contents --" << endl;
    cout << filename << endl;
    cout << "-- End --" << endl;
    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}


Errors:
Line |38|error: expected primary-expression before '>' token|

Line |38|error: expected primary-expression before '<' token|

Line |43|error: no match for 'operator>=' in 'file >= 'A''|

Line |43|error: no match for 'operator<=' in 'file <= 'Z''|
Type it as you say it, less than or equal to, <=, greater than or equal to, >=. Also, in you if statements, remove file, you're checking the variable c, so put that there instead. There is also a function in cctype to do exactly what your last two if statements do, they're islower() and isupper() respectively.

You're also not using the variable i at all, so remove that, and all areas where i is. You also don't need line 17 for anything, what was it for?
Last edited on
Thanks for your help. When I make those changes I get errors in everything in the if statement

error: could not convert 'std::isalpha ' to 'bool'

when I leave the 'c' in it will compile but it outputs the the samethnig that you input for the filename instead of the file contents and none of the if statements work either they all reported '0'.

Here is the 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
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
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
using namespace std;

int main()
{
    fstream file;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    string filename;


    cout << "Enter a file name" << endl;
    cin >> filename;

    file.open(filename.c_str(), ios::in);

        for (char c = file.get(); c !=EOF; c = file.get())
        {
            if (isalpha)
            {
                alpha_count++;
            }
            else if (ispunct(c))
            {
                punct_count++;
            }
            else if (isspace(c))
            {
                space_count++;
            }
            else if (islower(c))
            {
                lower_count++;
            }
            else if (isupper(c))
            {
                upper_count++;
            }
    }
    file.close();

    cout << "-- File contents --" << endl;
    cout << filename << endl;
    cout << "-- End --" << endl;
    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}
when I leave the 'c' in it will compile but it outputs the the samethnig that you input for the filename instead of the file contents and none of the if statements work either they all reported '0'.


It's because the 'c' is supposed to be inside the parenthesis, just like how you have it now. There is also an issue with you if/else if chain anyways. First, you check isalpha, but since you're not checking anything, it returns something that makes it true (honestly, I'm not even sure how/why it even compiles), so everything else is skipped.

I believe you wanted to do something differently though, if the variable, c, is alphabetic, you want to increment it. I think you might want to look up what is considered an alpha though. But like I said, if that evaluates to true, everything else is ignore since the else if's only get evaluated if the previous if was false.
I read your previous post wrong. I thought it said to remove the (c). The end goal is to have the program ask the user for a text file and then the program will output the entire file and the statistics of the file. I can't get it to do any of it now. It asks for the file and the it outputs the filename and all the statistics are 0.
You need to reread my previous post for information on the statistics. Also, make sure your file name is in the same folder as your program is. The folder for the .exe might be different. You also need to make sure the file existed prior or else it'll be blank.

As for your issue, it's not displaying the text in the file because you're not printing the text to the screen.

I just told you how to fix the statistics in my previous post. Pay close attention to the last section.
Last edited on
I made some changes and everything is working except for I can't get the entire contents of the text file to output to the screen.

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

int main()
{
    fstream file;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    string filename;


    cout << "Enter a file name" << endl;
    cin >> filename;

    file.open(filename.c_str(), ios::in);

    if(!file)
    {
        cout << "Couldn't open " << filename << endl;
        return 1;
    }
    else
    {
        for (char c = file.get(); c !=EOF; c = file.get())
        {
            if (islower(c))
            {
                lower_count++;
            }
            if (isupper(c))
            {
                upper_count++;
            }
            if (isalpha(c))
            {
                alpha_count++;
            }
            if (ispunct(c))
            {
                punct_count++;
            }
            if (isspace(c))
            {
                space_count++;
            }
        }

    }
    file.close();

    cout << "-- File contents --" << endl;
    cout << filename << endl;
    cout << "-- End --" << endl;
    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}
print each character right after you read it, line 31.
Thanks, i changed the code but I don't know how to get it to print the whole contents on one line. It is printing it one character per line instead of the entire contents on one line. Here is what I have now.

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

int main()
{
    fstream file;
    int lower_count = 0;
    int upper_count = 0;
    int alpha_count = 0;
    int space_count = 0;
    int punct_count = 0;
    string filename;


    cout << "Enter a file name" << endl;
    cin >> filename;

    file.open(filename.c_str(), ios::in);

    if(!file)
    {
        cout << "Couldn't open " << filename << endl;
        return 1;
    }
    else
    {
        for (char c = file.get(); c !=EOF; c = file.get())
        {
            cout << "-- File contents --" << endl;
            cout << c << endl;
            cout << "-- End --" << endl;cout << c << endl;

            if (islower(c))
            {
                lower_count++;
            }
            if (isupper(c))
            {
                upper_count++;
            }
            if (isalpha(c))
            {
                alpha_count++;
            }
            if (ispunct(c))
            {
                punct_count++;
            }
            if (isspace(c))
            {
                space_count++;
            }
        }

    }
    file.close();


    cout << "File statistics:" << endl;
    cout << "Uppercase characters: " << upper_count << endl;
    cout << "Lowercase characters: " << lower_count << endl;
    cout << "Punctuation characters: " << punct_count << endl;
    cout << "Alphabetic characters: " << alpha_count << endl;
    cout << "Whitespace characters: " << space_count << endl;
}
I recommend looking at your code and figuring out why it's printing a new line.
Pages: 12