0

For class I am required to write a program that takes input from a .txt file, converts it to pig latin using c_strings and then outputs the results to another .txt file. I have tested each of my functions on their own as well as using a for() loop to iterate through about 40 calls to the functions. When I pass around 60 calls though I get a Debug Assertion Failed! popup stating

"File: minkernel\crts\ucrt\inc\corect_internal_string_templates.h

Line: 50

Expression:(L"Buffer is too small" && 0)"

Here is my call to the functions.

while(!inputFile.eof())
  {
     engStr = readDataFromFile(inputFile);
     pLatinStr = convertToPigLatin(engStr, pLatinStr);
     outPutResults(outputFile, engStr, pLatinStr);
  }

and here are the functions being called.

    char * readDataFromFile(ifstream &inFile)
{
   char * arr = new char[20];

   inFile.getline(arr, 15);

   return arr;
   delete[] arr;
}

bool checkVowel(char * engStr, int count)
{
   if (
      engStr[count] == 'a' ||
      engStr[count] == 'e' ||
      engStr[count] == 'i' ||
      engStr[count] == 'o' ||
      engStr[count] == 'u'
      )
      return true;
   else
      return false;
}

char * convertToPigLatin(char * engStr, char * pLatinStr)
{
   char * arr = new char[20];
   int count = 0;
   pLatinStr = arr;

   while (engStr[count] != '\0')
   {
      bool vowel = checkVowel(engStr, count);
      if (vowel && count == 0)
      {
         stringCopyVowelFirst(pLatinStr, engStr);
         break;
      }
      else
         if (vowel)
         {
            stringCopyAfterVowel(pLatinStr, engStr, count);
            break;
         }
      count++;
   }

   return pLatinStr;
   delete[] arr;
}

void stringCopyAfterVowel(char *& pLatinStr, char * engStr, int count)
{
   int LtnIndex = 0;
   char ayStr[] = "ay\0";
   char tempStr[20];
   tempStr[0] = 0;

   strcpy_s(pLatinStr, 15, engStr);
   strncat_s(tempStr, strlen(tempStr) + 10, engStr, count);

   while (engStr[count] != '\0')
   {
      pLatinStr[LtnIndex] = engStr[count];
      count++;
      LtnIndex++;
   }

   pLatinStr[LtnIndex] = '-';
   pLatinStr[LtnIndex + 1] = '\0';

   strcat_s(pLatinStr, 15, tempStr);
   strcat_s(pLatinStr, 15, ayStr);
}

void stringCopyVowelFirst(char *& pLatinStr, char * engStr)
{
   char wayStr[] = "-way\0";

   strcpy_s(pLatinStr, 15, engStr);
   strcat_s(pLatinStr, 15, wayStr);
}

void outPutResults(ofstream &outFile, char * engStr, char * pLatinStr)
{
   outFile.open("pigLatinOut.txt", std::ofstream::app);

   outFile << left << setw(12) << engStr << "\t";
   outFile << setw(14) << pLatinStr << endl;

   outFile.close();
}

Any help is greatly appreciated. This is about my third week studying c++.

Community
  • 1
  • 1
Joe
  • 3
  • 3
  • Probably off topic: `while(!inputFile.eof())` almost never works. Read more here: http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – user4581301 Jun 24 '16 at 01:42
  • One of the strings you're passing into an `_s` function is too long for the provided buffer. For example, in `strcpy_s(pLatinStr, 15, engStr);` if `engstr` is longer than 15 characters, boom. Hard to tell which call is blowing up without knowing your input, but there are pretty good odds that the debugger in whatever development environment you are using will stop on the assert and allow you to inspect the back trace that lead up to the assert. Very useful tool to get a handle on early, the debugger. Saves tonnes of time. – user4581301 Jun 24 '16 at 01:48
  • `strncat_s(tempStr, strlen(tempStr) + 10, engStr, count);` - this is wrong, the second parameter must be the number of characters in `tempStr` (in this case 20). Se – user253751 Jun 24 '16 at 01:51
  • You twice have `return foo; delete [] bar;` - your compiler should have told you that the `delete` is not reachable. – Ken Y-N Jun 24 '16 at 01:52
  • @KenY-N His assignment requires him to use C strings, not `std::string`. – Barmar Jun 24 '16 at 01:55
  • @KenY-N points out something pretty important there that needs a bit more expansion. You most definitely do not want to `new` `delete` and `return` the same memory in the same function (at least not without some conditional logic separating the `delete` and the `return`). Once memory is deleted, it's gone. The receiver can't use what was returned, and unfortunately it's not something the compiler can easily catch and warn you about. – user4581301 Jun 24 '16 at 01:57
  • @user4581301 thanks for the help! – Joe Jun 24 '16 at 05:40
  • @KenY-N so you create a function that deletes the dynamic memory at the end of the main function, ? Or is there a more efficient way of dealing with it? – Joe Jun 24 '16 at 05:40
  • Yes, basically; you have to tidy up after yourself. Your assignment rules forbid it, it seems, but `std::string` can manage the memory for you, or you can use smart pointers like [`std::shared_ptr`](http://en.cppreference.com/w/cpp/memory/shared_ptr), but that might be a bit advanced for your third week of C++! – Ken Y-N Jun 24 '16 at 05:46
  • To be honest, I'd call smart pointers less advanced. What's going on behind the scenes is some groovy and complicated juju, but it doesn't take much understanding or appreciation of the deep magic to use it. That said if teach says no string, you can bet your backside they'd freak over a unique_ptr. Often the best thing to do is not use dynamic allocation at all. For example, you can declare an array (`char buffer[15];`) and pass it into a function to be filled out, manipulated, or whatever (`bool readFromFile(ifstream &inFile, char *buffer)`). You'll find most of the time you don't need `new` – user4581301 Jun 24 '16 at 07:06
  • Great I got everything to work guys. I increased the size of my buffer when using the 'strcpy_s()' function and I also changed 'strncat_s(tempStr, strlen(tempStr)+10, engStr, count);' to 'strncat_s(tempStr, strlen(engStr)+1, engStr, count);'. Also I added a deleteDynMem bool so that once the output of the program is complete the bool function becomes true and then it goes back into those other functions to delete the memory. Thanks so much for your help guys! – Joe Jun 24 '16 at 15:53

0 Answers0