Trying to find the number of words without counting the spaces - c++

I am trying to find the number of words in from the input by user but i am asked not to find it through counting the spaces since the user can input a single letter and a bunch of spaces and it will count it as number of words
I have tried it with counting the number of spaces but i can not think of another way to count the number of words
char Array[100];
{
//variable declaration
int words = 0;
// input
cout << "Enter string: ";
cin.getline(Array, 100);
// Number of words
for (int i = 0; i < strlen(Array); i++)
{
if (Array[i] == ' ')
words++;
}
cout << "Number of words in the string are: " << words + 1;
cout << endl;
}
I want to find the number of words with another method rather than counting it through the number of spaces.Any help is appreciated.I am a beginner so could you not use something complicated to solve the problem like a getloc.

You just have to count the number of times the space character is followed immediately by a non-space character.
int firstNonSpace = 0;
while (Array[firstNonSpace] == ' ') //to skip spaces at the beginning of input
{
firstNonSpace++;
}
for (int i = firstNonSpace; i < strlen(Array) - 1; i++)
{
if (Array[i] == ' ' && Array[i+1] != ' ')
words++;
}
if(words || firstNonSpace == 0)
words++; //do not increment if the input is empty or only spaces.
cout << "Number of words in the string are: " << words;
See Live Demo
Note that you will have to handle the case when the input exceeds the bounds of the array so as not to run into undefined behavior.

The easiest way is to let the standard library parse the words for you, eg:
#include <iostream>
#include <string>
#include <sstream>
int main () {
//variable declarations
std::string line, word;
int words = 0;
// input
std::cout << "Enter string: ";
std::getline(std::cin, line);
// Number of words
std::istringstream iss(line);
while (iss >> word) {
++words;
}
std::cout << "Number of words in the string are: " << words << std::endl;
return 0;
}
If you don't want to use std::string (ie, to avoid memory allocations), you could do this instead:
#include <iostream>
#include <algorithm>
#include <cctype>
int main() {
//variable declarations
char Array[100];
int words = 0;
// input
std::cout << "Enter string: ";
std::cin.getline(Array, 100);
// Number of words
char *ptr = Array;
char *end = ptr + std::cin.gcount();
while (ptr != end) {
ptr = std::find_if(ptr, end, [](char c){ return !std::isspace(static_cast<unsigned char>(c)); });
if (ptr == end) break;
ptr = std::find_if(ptr+1, end, [](char c){ return std::isspace(static_cast<unsigned char>(c)); });
++words;
}
std::cout << "Number of words in the string are: " << words << std::endl;
return 0;
}
Or, if you want to completely avoid standard library algorithms:
#include <iostream>
int main() {
//variable declarations
char Array[100];
int words = 0;
// input
std::cout << "Enter string: ";
std::cin.getline(Array, 100);
// Number of words
char *ptr = Array;
char *end = ptr + std::cin.gcount();
while (ptr != end) {
while ((*ptr <= ' ')) && (ptr != end)) ++ptr;
if (ptr == end) break;
++ptr;
while ((ptr != end) && (*ptr > ' ')) ++ptr;
++words;
}
std::cout << "Number of words in the string are: " << words << std::endl;
return 0;
}
You could then wrap the parsing into a helper function to clean up the counting loop:
#include <iostream>
//#include <algorithm>
//#include <cctype>
bool findNextWord(char* &begin, char *end) {
/*
begin = std::find_if(begin, end, [](char c){ return !std::isspace(static_cast<unsigned char>(c)); });
if (begin == end) return false;
begin = std::find_if(begin+1, end, [](char c){ return std::isspace(static_cast<unsigned char>(c)); });
return true;
*/
while ((begin != end) && (*begin <= ' ')) ++begin;
if (begin == end) return false;
++begin;
while ((begin != end) && (*begin > ' ')) ++begin;
return true;
}
int main() {
//variable declarations
char Array[100];
int words = 0;
// input
std::cout << "Enter string: ";
std::cin.getline(Array, 100);
// Number of words
char *ptr = Array;
char *end = ptr + std::cin.gcount();
while (findNextWord(ptr, end)) {
++words;
}
std::cout << "Number of words in the string are: " << words << std::endl;
return 0;
}

Just do the following change and bob's your uncle :)
if(array[i] == ' ') {
continue;
}
words++;
while(array[i] != ' ') {
i++;
}

I was looking online and found them all very confusing this is simple and works
string state;//variable for statement the user may enter
int i; //variable for the for loop
int wordtally; // variable for word count
//this checks if its a space or not and then if it is a space it loops untill it
//reaches a character then after reaching a character loops until it hits a space anmd
//when that happens the counter goes up making it so every time a blank amount of spaces
//then a word it increases word count
for ( i=0 ; i < state.length() ; i++ )
{
if(state[i]==' '){
do {
i++;
}while(state[i]==' ');
}
else if(state[i]>=' '){
do {
i++;
}
while(state[i]>' ');
wordtally++ ;
}
}

Related

Wordcount function having trouble adding words to a set of unique words

I'm writing a wordcount function that should be able to read elements from stdin into a string. Then evaluate the string and return the number of words, number of lines, size of the string, and the number of unique words.
My issue is when it comes to adding words to the unique set. When I write it to add elements to a set, it would count the whitespace as part of the word then push entirely into my set.
Example:
Input:
this is
is
a test
test
Output
a
test
is test this
line is 4
Words = 7
size is 27
Unique is 6
It counts 7 words in total and 6 unique. I tried debugging it by printing bits of the code as i go so i can keep track of where I went wrong. I can only conclude that the issue lies within my if loops. How can I get past this, I've been stuck for some time now.
Here is my code:
#include<iostream>
#include<string>
#include<set>
using std::string;
using std::set;
using std::cin;
using std::cout;
set<string> UNIQUE;
size_t sfind(const string s) //will take string a count words, add to set
{
string a;
int linecount = 0;
int state = 0; //0 represents reading whitespace/tab, 1 = reading letter
int count = 0; //word count
for(size_t i =0; i < s.length(); i++) {
a+=s[i]; //add to new string to add to set
if(state ==0) { //start at whitespace
if(state != ' ' && state != '\t') { //we didnt read whitespace
count++;
state =1;
}
}
else if(s[i]== ' ' || s[i] == '\t' || s[i] == '\n') {
state = 0;
UNIQUE.insert(a); //add to UNIQUE words
a.clear(); // clear and reset the string
}
if (s[i] == '\n') {
linecount++;
}
}
for(set<string>::iterator i = UNIQUE.begin(); i!= UNIQUE.end(); i++) {
cout << *i;
}
cout << '\n';
cout << "line is " << linecount << '\n';
return count;
}
int main()
{
char c;
string s;
while(fread(&c,1,1,stdin)) {
s+=c; //read element add to string
}
cout << "Words = " << sfind(s) << '\n';
cout << "size is " << s.length() << '\n';
cout << "Unique is "<< UNIQUE.size() << '\n';
return 0;
}
Also I will be using
fread(&c,1,1,stdin)
because i will be using it later on with a larger wordcount function.
Rather than writing code trying to parse the string on spaces, use std::istringstream to do the parsing.
Here is an example:
#include <string>
#include <iostream>
#include <sstream>
#include <set>
int main()
{
std::set<std::string> stringSet;
std::string line;
while (std::getline(std::cin, line))
{
std::istringstream oneline(line);
std::string word;
while (oneline >> word)
{
std::cout << word << "\n";
stringSet.insert(word);
}
}
std::cout << "\n\nThere are " << stringSet.size() << " unique words";
}
Live Example

having a difficulty with making a palindrome program c++ [duplicate]

This question already has answers here:
std::cin input with spaces?
(8 answers)
Closed 7 years ago.
Hi this is my code for the palindrome program:
void palindrome()
{
string input;
bool checkInput, palindrome;
palindrome = true;
do
{
checkInput = false;
cout << "Enter a word, phrase or sentence :\n";
getline(cin, input);
for (unsigned int i = 0; i < input.size(); i++)
{
if (input[i] < 65 || input[i] > 90 && input[i] < 97 || input[i] > 122)
{
checkInput = true;
}
}
} while (checkInput);
for (unsigned int i = 0, j = input.size() - 1; i < input.size(); i++, j--)
{
if (input[i] != input[j] && input[i] + 32 != input[j] && input[i] - 32 != input[j])
{
palindrome = false;
break;
}
}
if (palindrome)
{
cout << "\n\nTo consider only letters and digits:\n";
cout << input << "\nYes, it is palindrome!\n";
cout << "\t\t Press <Enter> key back to menu";
fflush(stdin);
cin.get();
}
else
{
cout << "\n\nTo consider only letters and digits:\n";
cout << input << "\nNOPE, it's not palindrome\n";
cout << "\t\t Press <Enter> key back to menu";
fflush(stdin);
cin.get();
}
}
and when my input is racecar it reads and says it is a palindrome, but when my input is race car (with a space) it doesn't read and it says its not a palindrome.
My intend is to ignore all the spaces. Any help will be much appreciated!
Thanks in advance!
**editted
so i switched my cin >> input to getline(cin, input) and it doesnt let me input my words or phrases
Maybe it will work if you first remove all whitespaces after reading the Input?
#include <algorithm>
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
Whitespaces are not in die ASCII values you are checking, so the whileloop ends at the first whitespace.
The Problem
The palindrome is a word that is spelled backwards and forwards the same. Therefore, you can be sure that, going from the outside in, the letters need to be the same until you're examining the same letter (the total number of letters are odd) or the letter-searching things/examiners/markers (let's call them iterators) criss-cross.
How do you examine pair of letters from outside to inside? By using an index loop from the first to last position in tandem with a last-to-first index loop.
How You Do it (The Implementation)
Let's pretend we have two variables to act as the iterators, i and j. i will move forward while j will move backward. They will start at opposite ends:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
//This is where our word will be.
std::string str;
//Get input
std::cout << "Input your word, please!" << std::endl;
std::getline(std::cin, str);
//Let's use std::erase to take away our whitespaces from the
//C++11 library <algorithm>
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
//Initialize i and j, our iterators
//I use auto because the iterator type is long. It's a reason why auto was invented.
auto i = str.begin();
auto j = str.end() - 1;
//You see, str.end() is actually the END, and not the last letter.
//That's why it has a -1.
bool is_palindrome = true;
while (i < j) //While the two haven't crossed yet
{
//This std::cout shows you what i and j are at each repeat
std::cout << "i = " << *i << " ||| j = " << *j << std::endl;
//If the two characters marked by the two iterators are not equal
if (*i != *j)
{
is_palindrome = false;
break;
}
else
{
//Let's continue.
++i;
--j;
}
}
//If the loop gets to this point successfully, it's a palindrome.
if (is_palindrome)
std::cout << str << " is a palindrome!" << std::endl;
else
std::cout << str << " is not a palindrome." << std::endl;
return 0;
}
Hopefully this will help you. Remember to compile with -std=c++11 for C++11 features!
See if this works.
for (unsigned int i = 0, j == input.size() - 1; i < input.size();)
{
//Ignore spaces
if (input[i] == ' ')
{
++i; continue;
}
if (input[j] == ' ')
{
--j;continue;
}
//Automatic palindrome analysis
if (input[i] != input[j])
{
palindrome = false;
break;
}
++i;--j;
}

How to count unique words in string and output line where they occur? C++

So I'm working on this homework assignment and I'm really having trouble. I'm supposed to count the number of words more than two characters(have to contain one letter), unique words, and the number of times each unique word appears in the Programming Execution Environment. I'm also supposed to get input to search for in the PEE and output the number of times it appears and the line where it appears. I have some of it working, but I'm really struggling with counting how many times each word appears. I know my code is really bad right now, but that's why I'm here. I'm really struggling with these string functions for some reason. Any help is really appreciated!
#include <iostream>
#include <cstring>
#include <string>
#include <cctype>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
//PEE string
string envstr("");
bool checkChar(unsigned c)
{
return (ispunct(c) || isspace(c) || isblank(c) || isdigit(c) || c == '\n');
}
void searchWord(unsigned c, size_t length)
{
multiset<string> words;
vector<string> vwrds; //this was something i was trying out
string tempword;
while (!checkChar(envstr[c]) && c < length)
{
tempword = tempword + envstr[c]; //problem here
c++;
}
tempword = tempword + " ";
vwrds.push_back(tempword);
words.insert(tempword); //this is just a bunch of random letters
tempword.clear();
//for (multiset<string>::const_iterator i(words.begin()), end(words.end()); i != end; i++)
//cout << *i;
}
bool checkIfWord(char c)
{
bool valid = false;
int i;
for (i = c; i > c - 2; i--)
{
if (!checkChar(envstr[i]))
valid = true;
}
if (valid)
searchWord(i, envstr.length());
return valid;
}
int main()
{
//this code given by my instructor
extern char **environ; // needed to access your execution environment
int k = 0;
size_t wordCount = 0;
while (environ[k] != NULL)
{
cout << environ[k] << endl;
string str(environ[k]);
envstr = envstr + str;
k++;
}
//iterator to count words
wordCount = count_if(envstr.begin(), envstr.end(), checkIfWord);
cout << "\nThe PEE contains " << wordCount << " words. \n";
//transform environment string to lowercase
transform(envstr.begin(), envstr.end(), envstr.begin(), tolower);
string input;
do
{
cout << "Enter your search item: \n";
cin >> input;
//string can only be forty characters
if (input.length() > 40 || input == "\n")
{
cout << "That search query is too long. \n";
continue;
}
//change the search string to lowercase, like the envstr
transform(input.begin(), input.end(), input.begin(), tolower);
int j = 0;
int searchCount = 0;
vector<size_t> positions;
size_t pos = envstr.find(input, 0);
//search for that string
while (pos != string::npos)
{
positions.push_back(pos);
pos = envstr.find(input, pos + 1);
searchCount++;
}
cout << "\nThat phrase occurs a total of " << searchCount << " times.\n";
cout << "It occurs in the following lines: \n";
//output where that string occurs
for (vector<size_t>::iterator it = positions.begin(); it != positions.end(); ++it)
{
for (int i = *it; i < envstr.length() - 1 && checkChar(envstr[i]); i++)
{
cout << envstr[i];
}
cout << endl;
}
positions.clear();
} while (input != "END");
cin.get();
return 0;
}
First, your function checkChar() returns false when the parameter is a char, so if you want to print where that string occurs, it should be:
for (int i = *it; (i < envstr.length() - 1) && !checkChar(envstr[i]); i++)
{
cout << envstr[i];
}
Second, the code for counting words makes no sense and there is a potential out-of-bounds here: if (!checkChar(envstr[i])), I would suggest you to split the string using delimter '\', then do something.

How to remove punctuation characters from a char array?

My program prompts a user for a phrase to check if its a palindrome, then it's supposed to print out the phrase without capitalization or special characters like " ' , ? etc. My problem is erasing those characters. I've gotten my program to ignore them I'm asking how should I erase them? I made a comment where I think the statement should go. Example output should be: "Madam I'm Adam" to "madamimadam"
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
//Variables and arrays
int const index = 80;
char Phrase[index];
char NewPhrase[index];
int i, j, k, l;
bool test = true;
//Prompt user for the phrase/word
cout << "Please enter a sentence to be tested as a palindrome: ";
cin.getline(Phrase, 80);
//Make everything lowercase, delete spaces, and copy that to a new array 'NewPhrase'
for(k = 0, l = 0; k <= strlen(Phrase); k++)
{
if(Phrase[k] != ' ')
{
NewPhrase[l] = tolower(Phrase[k]);
l++;
}
}
//cout << "The Phrase without punctuation/extra characters: " << newPhrase[l];
int length = strlen(NewPhrase); //Get the length of the phrase
for(i = 0, j = length-1; i < j; i++, j--)
{
if(test) //Test to see if the phrase is a palindrome
{
if(NewPhrase[i] == NewPhrase[j])
{;}
else
{
test = false;
}
}
else
break;
}
if(test)
{
cout << endl << "Phrase/Word is a Palindrome." << endl << endl;
cout << "The Palindrome is: " << NewPhrase << endl << endl;
}
else
cout << endl << "Phrase/Word is not a Palindrome." << endl << endl;
system("Pause");
return 0;
}
Modify this line:
if(Phrase[k] != ' ')
To be:
if((phrase[k] != ' ') && (ispunct(phrase[k]) == false))
This means that we check for spaces and punctuation at the same time.
Also, consider rewriting this:
if(NewPhrase[i] == NewPhrase[j])
{;}
else
{
test = false;
}
As this:
if(NewPhrase[i] != NewPhrase[j])
test = false;
Here's suggestion:
Use an std::string
Use std::ispunct to determine whether a character in the string is a punctuation mark
Use the erase-remove idiom to remove punctuation
That is one line of code (plus one extra line for a convenience lambda):
std::string phrase = .....;
auto isPunct = [](char c) { return std::ispunct(static_cast<unsigned char>(c)); }
phrase.erase(std::remove_if(phrase.begin(), phrase.end(), isPunct),
phrase.end());
Next, for turning into lower case, from my answer to this recent question, another one-liner:
std::transform(phrase.begin(), phrase.end(), phrase.begin(),
[](char c)
{ return std::tolower(static_cast<unsigned char>(c));});

Extra Characters Inserted Into Array

I'm a C++ beginner and wrote a program to check if two phrases are anagrams. The characters are being read one at a time and stored in an array. I have everything working, except in some cases, extra characters are being inserted into the array.
For example, if I enter the phrases aabb and abba, this is the output of the program:
Enter two lines that might be anagrams:
--> aabb
--> abba
String A is aabb
String B is abbai?
The two strings are NOT anagrams.
They should be anagrams, but for some reason, i? is added into the array, causing the phrases to not be anagrams. I'm probably overlooking a simple mistake in the code, but would really appreciate any feedback.
Here is the code:
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int check_anagram(char [], char []);
int main()
{
char ch, a[60], b[60];
int flag, i;
cout << "Enter two lines that might be anagrams:" << endl;
cout << "--> ";
cin.get(ch);
ch = tolower(ch);
i = 0;
while (ch != '\n')
{
if (ch > '#') {
a[i] = ch;
i++;
}
cin.get(ch);
ch = tolower(ch);
}
cout << "--> ";
cin.get(ch);
ch = tolower(ch);
i = 0;
while (ch != '\n')
{
if (ch > '#') {
b[i] = ch;
i++;
}
cin.get(ch);
ch = tolower(ch);
}
flag = check_anagram(a, b);
cout << "String A is " << a << endl;
cout << "String B is " << b << endl;
cout << "The two strings ";
if (flag == 1)
cout << "ARE";
else
cout << "are NOT";
cout << " anagrams." << endl << endl;
return 0;
}
int check_anagram(char a[], char b[])
{
int first[26] = {0}, second[26] = {0}, c = 0;
while (a[c] != '\0')
{
first[a[c]-'a']++;
c++;
}
c = 0;
while (b[c] != '\0')
{
second[b[c]-'a']++;
c++;
}
for (c = 0; c < 26; c++)
{
if (first[c] != second[c])
return 0;
}
return 1;
}
Thanks in advance!
You just need to terminate the two character arrays with '\0' because the logic in check_anagram treats both arrays as NULL-terminated.
..
while (ch != '\n')
{
if (ch > '#') {
a[i] = ch;
i++;
}
cin.get(ch);
ch = tolower(ch);
}
a[i] = '\0'; // <<<<<<<< Add this line
cout << "--> ";
cin.get(ch);
ch = tolower(ch);
i = 0;
while (ch != '\n')
{
if (ch > '#') {
b[i] = ch;
i++;
}
cin.get(ch);
ch = tolower(ch);
}
b[i] = '\0'; // <<<<<<<< Add this line
..
Here is the result:
Enter two lines that might be anagrams:
--> aabb
--> abba
String A is aabb
String B is abba
The two strings ARE anagrams.