Solved

Problem with strings

Posted on 2006-11-07
12
468 Views
Last Modified: 2012-10-11
here is what I have to do

Write a program that will read in a line of text and output the number of words in the line and the number of occurrences of each letter. Define a word to be any string of letters that is delimited at each end by either whitespace, a period, a comma, or the beginning or end of the line. You can assume that the input consists entirely of letters, whitespace, commas, and periods. When outputting the number of letters that occur in a line, be sure to count upper-case and lowercase versions of a letter as the same letter. Output the letters in alphabetical order and list only those letters that do occur in the input line. For example, the input line

I say Hi.

should produce output similar to the following:

3 words
1 a
1 h
2 i
1 s
1 y



Here is what I have
Can someone help me on what to do next?



#include <iostream>
#include <cctype>

using namespace std;

void readAndCount (int &numWords, int letterCount[]);
void outputLetterCounts (int letterCount[]);

int main()
{
  int numWords;
  int letterCount[26];

  cout << endl;
  cout << "Enter a line of text.." << endl << endl;

  readAndCount (numWords, letterCount);

  cout << endl;
  cout << numWords << " words" << endl;
  outputLetterCounts(letterCount);
 
  return 0;
}

void readAndCount (int &numWords, int letterCount[])





void outputLetterCounts (int letterCount[])





void outputLetterCounts(int letterCount[])
{
  for (int i = 0; i < 26; i++)
    {
      if (letterCount[i] > 0)
      {
        cout << letterCount[i] << " " << char('a' + i) << endl;
      }
    }
}
0
Comment
Question by:alohadin
  • 4
  • 4
  • 3
  • +1
12 Comments
 
LVL 13

Expert Comment

by:marchent
Comment Utility
#include<string.h>
int count_letter[130]; //initially 0
void readAndCount()
{
    puts("enter a line");
    char buffer[100];
    char *p;
    int i,word_count = 0;
    gets(buffer);
    //start counting latters
    for(i=0;i<strlen(buffer);i++)
    {
        if(buffer[i]>='a' && buffer[i]<='z')//a-z
            count_letter[buffer[i]]++;
        else if(buffer[i]>='A' && buffer[i]<='Z') //A-Z
            count_letter[buffer[i] + 32]++;
    }
    //snd counting latters
    //start counting words
    p = strtok(buffer," ");
    while(p!=NULL)
    {
        word_count++;
        p = strtok(NULL," ");
    }
    //end counting words
    printf("%d words\n",word_count);
    for(i='a';i<='z';i++)
        if(count_letter[i])
            printf("%d %c\n",count_letter[i],(char)i);
}

use cout and cin for input and output values, if you want. and remember, strtok will change the value of buffer[] so if u need buffer[] in future, then u have to save it first before use strtok on it.

~marchent~
0
 
LVL 1

Author Comment

by:alohadin
Comment Utility
I get here many errors
I don't get it


I'm not very skilled in c++
I'm still learning things :(
0
 
LVL 13

Expert Comment

by:marchent
Comment Utility
just use #include<string.h> not #include<string> or u can use both

and whats are the errors !!!

~marchent~
0
 
LVL 28

Expert Comment

by:pepr
Comment Utility
marchent: Do not give bad advices. Of course that <string> should be used! The <string.h> is obsolete. Also, your solution is more C than C++ and does not fit with the assignment, nor with C++ practice.

alohadin: This looks like the homework -- it is the rule here not to give you a solution in such case. Have a look at getline() function in the <string>. Then read the doc related to the length() or size() methods of the std::string respective of its base class basic_string. Loop through the string, index the characters, and detect only the letters. Then learn how to convert characters to lower using tolower() from <locale> or possibly better (easier for the example) by just adding a constant to the ordinal number of the character. Then you need to transform the character into the index in the range from 0 to 25 and increment the value of the array element on that index. Also, the array have to be zeroed first.

Publish your code here to get some "Yes, this is O.K." or "No. This should be done differently" response.
0
 
LVL 28

Expert Comment

by:pepr
Comment Utility
... and prefer ++i if you really do not need the effect of i++
0
 
LVL 13

Expert Comment

by:marchent
Comment Utility
pepr

#include<string.h>
#include<string>
u can use both at a same time. they have their own library function

i thought this solution will help him, more than the solution of C++. in his given code he only used "cin" and "cout" from standard C++. so how can i assume that he is much capable to adopt from pure C++ ?

anyway thx for ur suggestion,
~marchent~
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 45 total points
Comment Utility
>>>> u can use both at a same time. they have their own library function

That is wrong. <string> and <string.h> are not supposed to get both included even if some compilers may tolerate it. The <string.h> is old C string header file and is regarded as deprecated when using younger C++ compilers. If you have to use old C (style) code and get problems when only including <string> - I never experienced these kind of problems - you may include <cstring> what includes <string.h> in a safe way.

>>>> more than the solution of C++

???? It's a very - strange - argumentation that C solutions should help more than C++ solutions ...

Listen, there is a C TA here where you can post such kind of comments without making a fool of yourself.

>>>> how can i assume that he is much capable to adopt from pure C++ ?

Again, it is the C++ TA here. How can you assume that he is capable to understand bad C code like the one above?

alohadin, I am sorry for spoiling your thread with that kind of discussions but if you want to learn C++ you should avoid that kind of code marchent gave you. As pepr told you we can help you only with code if you post your own attempts. You posted the prototype of the readAndCount function and I will give you the comments how to implement it

I think it is better you make three functions instead of one, one function for each task

    bool askForText(char textline[], int maxsize);
    int countWords(const char textline[]);
    countLetters(const char textline[], int letterCount[]);

// function to prompt "Enter a line of text" and read the text line from std::cin
bool askForText(char textline[], int maxsize);

Note, if you are allowed to use std::string you should replace  (char textline[], int maxsize) by (string& textline). If not, you have to create a suitable sized char buffer in main and pass it to askForText like that:

     char textline[256];
     if (askForText(textline, sizeof(textline))
     {
         ....
     }

Doing so, allows you to increase the size easily only by changing at one place.

The bool return is intended to allow the user to quit, e. g. by entering "quit" or "q". You should check the input for that and return either true or false.

With that you could ask and evaluate in a loop until the user eants to exit:

   while (true)
   {
       char textline[256];
       if (askForText(textline, sizeof(textline))
       {
         ....
       }
       else
            break;   // break the while(true) infinite loop
   }

    int countWords(const char textline[])
    {
         // get the length of inputline
         // init count to 0
          // have a loop to iterate any char
         //      check each char if it is one of the separators
         //      if yes and if the previous char wasn't a separator as well,  increment count
         // return count after loop
    }
    void countLetters(const char textline[], int letterCount[]);
    {
         // get the length of inputline
         // init count to 0
          // have a loop to iterate any char
         //      convert a temporary copy 'uc' of the char to upper case  
         //      check that char if it in the range ('A', 'Z')
         //      if yes increment letterCount at position uc - 'A'
    }

Regards, Alex
 
0
 
LVL 1

Author Comment

by:alohadin
Comment Utility
yeah I became a lil confsed while reading this discussion :)

thx for the help
I'll try it and post my code here
0
 
LVL 28

Expert Comment

by:pepr
Comment Utility
Thanks Alex, for supporting my view ;)

alohadin (and marchent), one more side note: If you want to master any programming language, you should strive for perfection also in your human language. It makes your brain better. Don't be lazy to write "you", "little", "thanks" and to press the Shift when typing the first letter of a sentence. If you think that you look more cool using the fancy abbreviations, you may blame yourself ;o) Programming requires perfection. Train it also in other areas. The "cool boys" are usually not "cool programmers".
0
 
LVL 1

Author Comment

by:alohadin
Comment Utility
pepr,
I'm not lazy to write full sentenses.
I allways write like that.
I wasn't allways a programmer. (I'm still not a real programmer, but I want to be)
English is not my mother language, and sometimes I don't find the right words, then I use abbreviations.



A friend helped me with this

here is the code:



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

using namespace std;

void readAndCount (int &numWords, int letterCount[]);

void Result (int letterCount[]);


int main()
{
  int numWords = 1;
  int letterCount[26];

  cout << endl;
  cout << "Enter a line of text.." << endl << endl;

  readAndCount (numWords, letterCount);

  cout << endl;
  cout << numWords << " words" << endl;
  Result(letterCount);
 
  return 0;
}

void readAndCount (int &numWords, int letterCount[])
{
  string line;
  int index;

  getline(cin, line);
 
  for (int i = 0; i < 26; i++)
  {
    letterCount[i] = 0;
  }

  for (int i=0; i<line.length(); i++)
  {
    if (isalpha(line[i]))
    {
      index = int(tolower(line[i]))-97;

      letterCount[index]++;
    }
   
    if (isspace(line[i]))
    {
      numWords++;
    }
  }
}

void Result(int letterCount[])
{
  for (int i = 0; i < 26; i++)
  {
    if (letterCount[i] > 0)
     {
        cout << letterCount[i] << " " << char('a' + i) << endl;
     }
  }
}



I will accept the answer of itsmeandnobodyelse , because he explained how to do it
0
 
LVL 28

Expert Comment

by:pepr
Comment Utility
alohadin: One way to make people thinking is to make them confused and a bit upset ;) I did not want to offend you. But I know that from now on "u" will sometimes remember that writing "... a lil confsed ... thx" is not that cool :-)

And use ++x instead of x++ whenever possible. And keep running ;-)

P.S. My first language is Czech, the second is Slovak, the third is Russian, and the fourth is English. I do a lot of mistakes in my English. I did not want to say you are stupid when you use "lil". I have just wanted to make you thinking about all of that.
0
 
LVL 1

Author Comment

by:alohadin
Comment Utility
I don't think it is cool to write like that.
When I chat on msn, I write like that
I can't do anything about it. It comes 'automaticly'. (you see, I can't find the right English word :p)

I'm not upset. It is ok that you said that.
I allready start thinking of it when writing :)

oh, and thanks for the tip about ++x
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now