0

so I am having a problem with getting my program to increment values properly.

My program needs to take a file in main(), and then pass that to a function-set to print that is called in main.

The key thing is that I need to use loops within the functions to get Letter Count, Space-Count, and Word Count.

I have the output configured right

cout << line_number << ": " << line << " [" << letter_count << " letters, " << space_count << " spaces, " << word_count << " words]" << endl;

Which results for example

0: Words go here. [# letters, # spaces, # words.]

But with my current functions for Letters and spaces, it doesn't work.

My non-space function for example

int count_non_space(string line) {
    int non_space = 0;
    for (int i = 0; i < line.length(); i++) {
        if (line.c_str() != " ") {
            non_space++;
        }
    }
    return non_space;

It counts all of the characters in the line instead and the counterpart (space_count) counts nothing.

And that's not to mention that I don't know how to count the words in the line.

Any advice as to what is going on? as I am certain that count_space and count_non_space should be inverses of each other (count_space being the same function but with == instead of !=)

EDIT: Got the Letter and Space count correct. Now, how would I get the word count from that sort of method?

EDIT 2: Okay so letter count is off. It is counting puncutation-characters (commas, periods, dashes, hiphons.etc) as leters.

I have managed to redact periods, dashes.etc from the code manually with a reduction if statement in the count_non_characters function.

But I can't add ' to it as it already uses '' to catch the char comparison

Is there catch-all term for punctuation characters in C++ that I can use for

if (line[i] == "Puncutation") {
   non_space--;
}

?

Malos323
  • 1
  • 1
  • So your goal is to count how many characters are not spaces? – Wais Kamal Sep 29 '21 at 19:36
  • 3
    `if (line.c_str() != " ")` doesn't make any sense - first of you are comparing pointers (which will never evaluate to `true`), second of you want to only compared the current character, so `if (line[i] != ' ')` – UnholySheep Sep 29 '21 at 19:36
  • Side note: `space_count = line.length() - letter_count;` and `word_count = space_count + 1;` (Assuming no leading/trailing space or multiple spaces.) – 001 Sep 29 '21 at 19:46
  • Thank you Sheep, that did fix space and non-space tracking. Now how would you recommend making a function to count words based on the lines? – Malos323 Sep 29 '21 at 19:46
  • Got it all working, thank you. – Malos323 Sep 29 '21 at 19:56
  • and nvm, Need letter count still off. – Malos323 Sep 29 '21 at 20:02

3 Answers3

0

If the goal is to count characters in a string that are not spaces, then there is a way to do this using the STL and lambdas that is much cleaner than writing a bunch of loops and worrying about updating variables.

int count_non_space(std::string line) {
    return std::count_if(line.begin(), line.end(),
                         [](auto ch) { 
                             return ch != ' '; 
                         });
}

This also makes is very straightforward to accommodate for things like spaces and tabs.

int count_non_space(std::string line) {
    return std::count_if(line.begin(), line.end(),
                         [](auto ch) { 
                             return ch != ' ' && ch != '\t'; 
                         });
}

To count the opposite (just the spaces) we simply need to change the condition in the lambda.

int space_count(std::string line) {
    return std::count_if(line.begin(), line.end(),
                         [](auto ch) { 
                             return ch == ' ' || ch == '\t'; 
                         });
}

As Remy Lebeau helpfully points out, we don't even have to write the lambda. We can simply use the std::isspace function directly instead of the lambda.

int space_count(std::string line) {
    return std::count_if(line.begin(), line.end(), std::isspace);
}

Documentation on std::count_if.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Chris
  • 26,361
  • 5
  • 21
  • 42
  • 1
    Consider using [`std::isspace()`](https://en.cppreference.com/w/cpp/string/byte/isspace) inside your lambdas, eg: `return std::count_if(line.begin(), line.end(), [](unsigned char ch) { return !isspace(ch); });` etc – Remy Lebeau Sep 29 '21 at 19:48
  • 1
    "*we don't even have to write the lambda*" - yes, you do, actually, because it is not safe to pass `char` values to `isspace()`, they need to be casted to `unsigned char`. This is explained in the `isspace()` reference I linked to. – Remy Lebeau Sep 29 '21 at 19:53
  • Thanks for continuing to assist! – Chris Sep 29 '21 at 19:54
0

As UnholySheep said, when you compare a c string (char *) you can't use standard logical operators. You will need to use strcmp(). However, if you use a c++ std::string then you can use compare() or logical operators.

As for finding words in a string. Here are a few resources.

For further help. Google: "Get word count per line c++"

Reminder, these two are different data types and have different library support:

  • std::string myStr
  • myStr.c_str()
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Frebreeze
  • 202
  • 3
  • 10
  • Yeah, I fixed that, and I am using an admittedly simpler form for word counting. But the final problem is that the letter-counting is catching punctuation characters as letters when it shouldn't,. I feel that can be solved with a reduction of count_non_spaces as a if-loop within the function (Aka if (line[i] == "punctuation") reduce the count for non_space characters. But I don't know if there is a catch-all for that in C++ or not as I don't know how to add things like hyphons to a "or" version of that if loop as I already use '' in the loop to compare against – Malos323 Sep 29 '21 at 20:12
  • I would look into using a regex to filter out undesired characters. "C++ Regex to remove punctuation" – Frebreeze Sep 30 '21 at 14:00
0

Here's how I would revise the function you gave:

int count_non_space(string line) {
    int non_space = 0;
    for (int i = 0; i < line.length(); i++) {
        if (line[i] != ' ') {
            non_space++;
        }
    }
    return non_space;
}

Notes:

  • I changed line.c_str() to line[i] in order to access the ith character of line
  • I changed " " to ' ' so that it's comparing against the space char, not a string which only contains the space. The comparison would fail if we were comparing the ith char to a string

As for this:

And that's not to mention that I don't know how to count the words in the line.

I don't know how your requirements define a word, but if we assume a word is any contiguous clump of non-space characters, you could use this logic:

  1. initialize bool in_word to false

  2. initialize int word_count to 0

  3. for each char in the string:

    1. if in_word is false and the current char is not a space, then set in_word to be true and increase word_count by 1
    2. if in_word is true and the current char is a space, then set in_word to be false
  4. return word_count

rkechols
  • 558
  • 5
  • 15
  • I did follow with that, and I have a way for word counts that seems to work well enough. But my letter counting seems to be catching punctuation characters in it when it shouldn't (periods, parenthesis, commas, hyphens). I assume I should do a reduction if statement inside the function to account for that but I don't know if there is a catch-all for punctuation terms that can be applied in that way for C++ – Malos323 Sep 29 '21 at 20:21
  • So you're talking about trying to count the number of letters? If you `#include ` you can use the `isalpha` function to determine if a char is alphabetic or not: https://www.cplusplus.com/reference/cctype/isalpha/ – rkechols Sep 29 '21 at 20:24