I'm kinda new to c++ and can only do very simple applications.
Could someone explain why this code works:

#include <iostream>
using namespace std;

int main()
{

    bool inword = 0;
    unsigned int numwords = 0;
	char *str = "this is a test string for my project";
    char letter;

    while (letter = *str++)
    {
        if(letter == ' ') 
        {
            inword = 0;
        }
        else if(inword == 0)
        {
            inword = 1;
            numwords++;
        }
    }
    cout << "Found " << numwords << " words!\n";
    system("PAUSE");
	return 0;
}

And this doesn't:

#include <iostream>
using namespace std;

int main()
{

    bool inword = 0;
    unsigned int numletters = 0;
	char *str = "this is a test string for my project";
    char letter;

    while (letter = *str++)
    {
        if(letter >= 'a' && letter <= 'z') 
        {
            inword = 0;
        }
        else if(inword == 0)
        {
            inword = 1;
            numletters++;
        }
    }
    cout << "Found " << numletters << " letters!\n";
    system("PAUSE");
	return 0;
}

Please help if you know any solution.

Dani AI

Generated

Short answer: the second snippet has its tests inverted and is fragile for input. That makes it count runs of non-letters instead of letters, and adding a trailing space only hides the bug. noticed the trailing-space symptom, pointed out the logic problem, and / were right to warn about unsafe pointer use — pointer arithmetic is okay only on a valid, null-terminated buffer that you own.

A simple, safer pattern uses std::string + std::getline and the C character-class helpers (with an unsigned-char cast). This reads a full input line and reliably counts words and letters:

#include <iostream>
#include <string>
#include <cctype>

int main() {
    std::string line;
    std::getline(std::cin, line);

    bool inword = false;
    unsigned words = 0, letters = 0;
    for (char ch : line) {
        unsigned char uc = static_cast<unsigned char>(ch);
        if (std::isalpha(uc)) {
            ++letters;
            if (!inword) { inword = true; ++words; }
        } else {
            inword = false;
        }
    }
    std::cout << "Found " << words << " words and " << letters << " letters\n";
}

Notes and quick tips:

  • Don’t use char *s = "literal" if you plan to modify or read user input; prefer std::string. String literals are read-only in modern C++.
  • If you must use a C buffer, use std::cin.getline(buf, N) to avoid overflow.
  • Always cast to unsigned char before calling std::isalpha/std::isspace to avoid UB on negative char values.
  • std::isalpha handles only single-byte locales; for Unicode-aware classification use a proper Unicode library.

This approach fixes the logic inversion and avoids the pointer/memory pitfalls discussed in the replies.

Recommended Answers

All 7 Replies

in first example counting the words at the begining of every word, in second example counting the words at following space (0x20). Try to add space after 'project'.

I think i see what you mean, but that's not the problem. How come it can count spaces but not letters?

Your 'else if' doesn't really make sense in the second one. If it's a-z you're obviously in a word, so no need to do that check, just increment the number of letters. (Especially since you don't even keep track of the number of words in the second example)

if(letter >= 'a' && letter <= 'z')
{
numletters++;
}

Thank you very much for your help, it works fine without the "else if". :cheesy:

Just one more small thing, how do I get the user to enter a line instead of declearing one in the code? Tried many things, but since i can't use "cin >> *str" I don't know what to do.

I appriciate any help.

Just one more small thing, how do I get the user to enter a line instead of declearing one in the code? Tried many things, but since i can't use "cin >> *str" I don't know what to do.

I appriciate any help.

you need to either declare a fixed size char array... i.e. str[100] or use dynamic memory and a deep copy using strcpy or stricpy. If you use the fixed size array you can cin >> str and all will be good.

however, this line will be/is problematic:

while (letter = *str++)

you're assigning letter the character one beyond the begining of str every time without a stop condition. I may be wrong, because I'm still a novice too, but shouldn't that keep on going beyond the end of str into other memory that wasn't allocated for str? You have a loop that will end only when the computer isn't able to assign letter a value... maybe that is why it works because you are dereferencing str, but I'm not positive on that one.

while (letter != '\n')

with an update of *str++ at the end of the loop, will make it better. That will help you with the user input check, because the loop will be testing for the new line that is created when the user hits enter at the end of their string. If they just hit enter, the loop will be skipped and all will be well.

I hope some of this helped. I'm still pretty much a noob at C++ and programming in general.

It may overwrite memory.

And if it may, then you're doing something wrong.
Pointer arithmetic should only be used when you know that the memory being pointed to is 'yours', such as in arrays and byte-order operations.
Otherwise, I think you're going to end up crashing and burning.

Edit: Of course, I'm pretty new myself, and tend to think that the sky will fall if I engage in code that only works 'sometimes'.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.