Raised This Month: $ Target: $400
 0% 

C++ getting char ocurences from a file


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Jheshka
Senior Member
Join Date: Dec 2005
Old 03-26-2009 , 13:50   C++ getting char ocurences from a file
Reply With Quote #1

How would I go about getting the amount of occurences that the char g appears in a file?
__________________
James
Jheshka is offline
PM
hello, i am pm
Join Date: Jan 2004
Location: Canalization
Old 03-26-2009 , 17:14   Re: C++ getting char ocurences from a file
Reply With Quote #2

You could do something like
Code:
#include <iostream>
#include <fstream>

int main(int argc, char* argv[])
{
   if (argc < 2)
   {
      std::cout << "Usage: countchars [filename]" << std::endl;
      return 1; 
   }

   std::ifstream file(argv[1]);
   
   if (file.bad())
   {
      std::cout << "Error opening file." << std::endl;
      return 1;
   }

   size_t count_g = 0;

   while (!file.eof())
   {
      if (file.get() == 'g')
         ++count_g;
   }

   std::cout << count_g << std::endl;

	return 0;
}
__________________
hello, i am pm
PM is offline
joaquimandrade
Veteran Member
Join Date: Dec 2008
Location: Portugal
Old 03-26-2009 , 17:18   Re: C++ getting char ocurences from a file
Reply With Quote #3

Quote:
Originally Posted by PM View Post
You could do something like
Code:
#include <iostream>
#include <fstream>

int main(int argc, char* argv[])
{
   if (argc < 2)
   {
      std::cout << "Usage: countchars [filename]" << std::endl;
      return 1; 
   }

   std::ifstream file(argv[1]);
   
   if (file.bad())
   {
      std::cout << "Error opening file." << std::endl;
      return 1;
   }

   size_t count_g = 0;

   while (!file.eof())
   {
      if (file.get() == 'g')
         ++count_g;
   }

   std::cout << count_g << std::endl;

    return 0;
}
And what about making the while like:

PHP Code:
   while (!file.eof())
       
count_g += (file.get() == 'g'
__________________
joaquimandrade is offline
PM
hello, i am pm
Join Date: Jan 2004
Location: Canalization
Old 03-26-2009 , 17:35   Re: C++ getting char ocurences from a file
Reply With Quote #4

Mmm, I guess it would compile and everything but (file.get() == 'g') is of the type bool in C++, some compilers will not like this, so it might be better to write

Code:
  while (!file.eof())
       count_g += (file.get() == 'g') ? 1 : 0;
__________________
hello, i am pm
PM is offline
joaquimandrade
Veteran Member
Join Date: Dec 2008
Location: Portugal
Old 03-26-2009 , 17:38   Re: C++ getting char ocurences from a file
Reply With Quote #5

Quote:
Originally Posted by PM View Post
Mmm, I guess it would compile and everything but (file.get() == 'g') is of the type bool in C++, some compilers will not like this, so it might be better to write

Code:
  while (!file.eof())
       count_g += (file.get() == 'g') ? 1 : 0;
My knowledge in C++ is limited to my knowledge in C,Java and C#. In Java it must be like you said.
__________________
joaquimandrade is offline
PM
hello, i am pm
Join Date: Jan 2004
Location: Canalization
Old 03-26-2009 , 17:43   Re: C++ getting char ocurences from a file
Reply With Quote #6

Actually IIRC bool is an integral type so it will get implicitly promoted to an int so the code you wrote should be no problem either.

BTW: file.bad() was wrong, use if (!file) instead.


EDIT:
If you want something cool, you could also do something like this:

Code:
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

template <class INT_TYPE, INT_TYPE WHAT>
class CGCounter
{
   size_t m_Count;
public:
   CGCounter() : m_Count(0)
   {
   }

   void operator () (INT_TYPE curElem)
   {
      if (curElem == WHAT)
         ++m_Count;
   }

   operator size_t () const
   {
      return m_Count;
   }
};

int _tmain(int argc, _TCHAR* argv[])
{
   if (argc < 2)
   {
      std::cout << "Usage: countchars [filename]" << std::endl;
      return 1; 
   }

   std::ifstream file(argv[1]);
   
   if (!file)
   {
      std::cout << "Error opening file." << std::endl;
      return 1;
   }

   std::cout << static_cast<size_t>(
      std::for_each(std::istream_iterator<char>(file), std::istream_iterator<char>(), CGCounter<char, 'g'>()))
      << std::endl;

	return 0;
}
istream_iterator<A> is a class which acts like a STL iterator and reads objects of type A from the stream.
for_each iterates from its first parameter to its second parameter (in this case istream_iterator<char>() constructs an interator which shows where to end ) and applies its third parameter on each element. Then it returns that third parameter again.
In this case the third parameter is CGCounter, a "functor", ie. a class which overloads operator() and thus looks like a function. You can specify what elements to count by specifying the type and the object to compare to in the template arguments (enclosed in < > ).
CGCounter also provides a conversion to size_t which simply returns the current counter value.
__________________
hello, i am pm

Last edited by PM; 03-26-2009 at 18:55.
PM is offline
Jheshka
Senior Member
Join Date: Dec 2005
Old 03-26-2009 , 23:44   Re: C++ getting char ocurences from a file
Reply With Quote #7

Thank you very much, PM
__________________
James
Jheshka is offline
joaquimandrade
Veteran Member
Join Date: Dec 2008
Location: Portugal
Old 03-27-2009 , 15:52   Re: C++ getting char ocurences from a file
Reply With Quote #8

Quote:
Originally Posted by PM View Post
Actually IIRC bool is an integral type so it will get implicitly promoted to an int so the code you wrote should be no problem either.

BTW: file.bad() was wrong, use if (!file) instead.


EDIT:
If you want something cool, you could also do something like this:

Code:
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

template <class INT_TYPE, INT_TYPE WHAT>
class CGCounter
{
   size_t m_Count;
public:
   CGCounter() : m_Count(0)
   {
   }

   void operator () (INT_TYPE curElem)
   {
      if (curElem == WHAT)
         ++m_Count;
   }

   operator size_t () const
   {
      return m_Count;
   }
};

int _tmain(int argc, _TCHAR* argv[])
{
   if (argc < 2)
   {
      std::cout << "Usage: countchars [filename]" << std::endl;
      return 1; 
   }

   std::ifstream file(argv[1]);
   
   if (!file)
   {
      std::cout << "Error opening file." << std::endl;
      return 1;
   }

   std::cout << static_cast<size_t>(
      std::for_each(std::istream_iterator<char>(file), std::istream_iterator<char>(), CGCounter<char, 'g'>()))
      << std::endl;

    return 0;
}
istream_iterator<A> is a class which acts like a STL iterator and reads objects of type A from the stream.
for_each iterates from its first parameter to its second parameter (in this case istream_iterator<char>() constructs an interator which shows where to end ) and applies its third parameter on each element. Then it returns that third parameter again.
In this case the third parameter is CGCounter, a "functor", ie. a class which overloads operator() and thus looks like a function. You can specify what elements to count by specifying the type and the object to compare to in the template arguments (enclosed in < > ).
CGCounter also provides a conversion to size_t which simply returns the current counter value.
Yes, it is very cool. Just a thing: Wouldn't it be more correct to say, instead of: "ie. a class which overloads operator() and thus looks like a function" , "ie. a class on which the operator () is overloaded and thus can be used as function"? That because, the class still looks like a class.
__________________
joaquimandrade is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 00:33.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode