-7
C++ Template:
class MyClass
{
public:
 getNiCount(...)
  {
  }
 replaceNiWithNI(...)
  {
  }
};
int main()
{
 const char *szTestString1 = "Ni nI NI nI Ni";
 const wchar_t *szTestString2 = L"Ni nI NI nI Ni";
 // Invoke getNiCount(...) of class MyClass
 // Invoke replaceNiWithNI(...) of class MyClass
 // Display on screen: "Found X occurrences of Ni. New string: Y"
}

Task description:

  1. Implement the two functions getNiCount and replaceNiWithNI of the class MyClass:
    • getNiCount should return the number of occurrences of "Ni" within szTestString1/2 (case sensitive)
    • replaceNiWithNI should replace all occurrences of "Ni" in szTestString1/2 with "NI" (case sensitive)
  2. Invoke the two functions getNiCount and replaceNiWithNI.
  3. Display the string given in the last comment on screen. X and Y should be replaced with the real values.
  4. The class MyClass should be able to deal with both szTestString1 (ASCII) and szTestString2 (Unicode).

General requirements:

The code should be

  • easy to understand and maintain (Priority 1)
  • technically elegant (Priority 2)
  • as (CPU) efficient as possible (Priority 3)

You’re allowed to use all techniques, toolkits and frameworks which are based on the C++ language.

my solution (incomplete)

The logic is below... However in my system the function2 "replace" is crashing. Cannot get it fixed.

#include<iostream>
#include<string>
using namespace std;

class MyClass
{
public:
 void getNiCount(const char*,const wchar_t*);
  //cout<<"\nCount is :"<<count;

void replaceNiWithNI(const char*,const wchar_t*);

};

void MyClass::getNiCount(const char* x,const wchar_t* y)
{
     int count=0;
     int ycount=0;
   for(int i=0; x[i]!='\0';i++)
   {
       if(x[i]=='N')
       {   if(x[i+1]=='i')
                          count++;
       }
       }
   for(int i=0; y[i]!='\0';i++)
   {
       if(y[i]=='N')
       {   if(y[i+1]=='i')
                          ycount++;
       }
       }
       cout<<"\nFound "<<count<<" occurences of Ni in String 1";
       cout<<"\nFound "<<ycount<<" occurences of Ni in String 2";
}

void MyClass:: replaceNiWithNI(const char* x,const wchar_t* y)
{    char* a;
     wchar_t* b;
     strcpy(a,x);


     for (int i=0;a[i]!='\0';i++)
     {
         if (a[i]=='N')
         {  if(a[i+1]=='i')
            {
                           a[i+1]='I';
                           }
         }
         }
     for (int i=0;y[i]!='\0';i++)
     {
         b[i]=y[i];
     }
     for (int i=0;b[i]!='\0';i++)
     {
         if (b[i]=='N')
         {  if(b[i+1]=='i')
            {
                           b[i+1]='I';
                           }
         }
     }

     cout<<"\nNew String 1 is :";
     puts(a);
     cout<<"\nNew String 2 is :";<<b

}


int main()
{
 const char *szTestString1 = "Ni nI NI nI Ni";
 const wchar_t *szTestString2 = L"Ni nI NI nI Ni";
 MyClass ob1;
 ob1.getNiCount(szTestString1,szTestString2);
 ob1.replaceNiWithNI(szTestString1,szTestString2);
 getchar();
 return 0;
}
Fraser
  • 74,704
  • 20
  • 238
  • 215

1 Answers1

4

There are a few issues here:

  1. Your program fails to compile because of the misplaced semi-colon in

    cout<<"\nNew String 2 is :";<<b
    
  2. Your program crashes at strcpy(a,x); because you're copying into a which is uninitialised - it has no memory allocated. You'd need to call new on a for this to work, which would also mean you'd need to know the size of the array required (another parameter for the function probably).

  3. Using std::string and std::wstring is almost always preferable to dealing with raw char arrays. See this question for example. I see you'd probably already considered it since you've got #include <string>

  4. Since you're required to perform identical operations on differing types, I suspect the point of the exercise might have been to use templates.

  5. You said

    getNiCount should return the number of occurrences...

    yet your getNiCount doesn't return anything.

  6. using namespace std; is often considered bad practice.

  7. It's generally worth favouring pre-increments rather than post-increments, although in this particular case, there's no overhead.


To give you an example including the recommendations above:

#include <iostream>
#include <string>

template<typename StrType>
class MyClass {
 public:
  int getNiCount(const StrType& input) const;
  void replaceNiWithNI(StrType& input) const;
};

template<typename StrType>
int MyClass<StrType>::getNiCount(const StrType& input) const {
  int count = 0;
  for (int i = 0; i < input.size() - 1; ++i) {
    if (input[i] == 'N' && input[i + 1] == 'i')
      ++count;
  }
  return count;
}

template<typename StrType>
void MyClass<StrType>::replaceNiWithNI(StrType& input) const {
  for (int i = 0; i < input.size() - 1; ++i) {
    if (input[i] == 'N' && input[i + 1] == 'i')
      input[i + 1] = 'I';
  }
}


int main() {
  const char* szTestString1 = "Ni nI NI nI Ni";
  MyClass<std::string> ob1;
  std::string testString1(szTestString1);
  int count1 = ob1.getNiCount(testString1);
  ob1.replaceNiWithNI(testString1);
  std::cout << "Found " << count1 << " occurences of Ni in String 1.  "
            << "New string: " << testString1 << '\n';

  const wchar_t* szTestString2 = L"Ni nI NI nI Ni";
  MyClass<std::wstring> ob2;
  std::wstring testString2(szTestString2);
  int count2 = ob2.getNiCount(testString2);
  ob2.replaceNiWithNI(testString2);
  std::wcout << L"Found " << count2 << L" occurences of Ni in String 2.  "
             << L"New string: " << testString2 << '\n';

  getchar();
  return 0;
}

I've generally left the way you locate and replace the Ni chars as you had it. There are more sophisticated options available in the member functions of std::string and in <algorithm> library.

Community
  • 1
  • 1
Fraser
  • 74,704
  • 20
  • 238
  • 215