1

Intermittently, Visual Studio throws an exception when running my code. I say intermittently because I've been able to successfully run my code without an error. The error was thrown after I created the function "print_Days."

The exception thrown is:

Debug Assertion Failed!

File: minkernel\crts\ucrt\corecrt_internal_string_templates.h

Line: 81

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

The function reads from a .txt file that has 7 days of the week listed (Monday thru Sunday) and then alphabetically sorts the days in a 2D c-string array (professor is making us use c-string instead of string unfortunately).

Here is all of my code:

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>

using namespace std;
//Constants for 2D array
const int NUM_OF_ROWS = 7; //Seven days listed in the file
const int NUM_OF_COLS = 10; //Longest word is 9 chars long, plus \0

void get_Days(ifstream& file, char days[][NUM_OF_COLS], int rows);
void sort_Days(char days[][NUM_OF_COLS], int rows);
void print_Days(const char days[][NUM_OF_COLS], const int rows);

void get_Days(ifstream& file, char days[][NUM_OF_COLS], int rows) {
   //Read from text file and return day
   for (int i = 0; i < rows; ++i)
   {
      file >> days[i];
   }
}

void sort_Days(char days[][NUM_OF_COLS], int rows) {
   //Sort the array alphabetically
   char temp[NUM_OF_COLS];
   for (int i = 0; i < rows; i++)
   {
      for (int j = 0; j < rows; j++)
      {
         if (strcmp(days[j - 1], days[j]) > 0)
         {
            strcpy_s(temp, days[j - 1]);
            strcpy_s(days[j - 1], days[j]);
            strcpy_s(days[j], temp);
         }
      }
   }
}

void print_Days(const char days[][NUM_OF_COLS], const int rows) {
   //Print the sorted array to the console
   for (int i = 0; i < NUM_OF_ROWS; ++i)
      for (int i = 0; i < rows; i++)
      {
         for (int j = 0; j < NUM_OF_COLS; j++)
         {
            cout << days[i][j] << endl;
         }
      }
}

int main() {
   //This program reads from a file (days.txt), sorts the days 
   // alphabetically, and then prints the result to the console.
   ifstream infile("days.txt");
   char days[NUM_OF_ROWS][NUM_OF_COLS];
   if (!infile)
   {
      cout << "File (days.txt) does not exist." << endl;
      return 1;
   }
   get_Days(infile, days, NUM_OF_ROWS);
   infile.close();
   sort_Days(days, NUM_OF_ROWS);
   print_Days(days, NUM_OF_ROWS);
   return 0;
}
Community
  • 1
  • 1
Chris
  • 191
  • 2
  • 12
  • 1
    You have two `for` loops that use `i` as the loop variable. – R Sahu Jan 20 '18 at 03:17
  • Look up the call stack in the debugger and see what line in your code is the problem. – 1201ProgramAlarm Jan 20 '18 at 03:23
  • @1201ProgramAlarm the call stack says the issue is line 35 which is "strcpy_s(temp, days[j - 1]);" – Chris Jan 20 '18 at 03:28
  • Visual Studio has a window called "Call Stack", you can trace back your error – Barmak Shemirani Jan 20 '18 at 03:51
  • The call stack lists Line 123 from "string.h" as triggering a breakpoint. The code at this line is: __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1( errno_t, strcpy_s, _Post_z_ char, _Destination, _In_z_ char const*, _Source ) And then the call stack lists Line 39 in my program, which is the first strcpy_s instance in the sort function. – Chris Jan 20 '18 at 04:01
  • What that's telling you is that `days[j - 1]` (or whatever the source string is) is longer than the buffer you're copying it in to (`temp`). What's the value of the source string, and how many characters are in it (counting the nul at the end)? – 1201ProgramAlarm Jan 20 '18 at 04:09
  • @1201ProgramAlarm The longest source string should have only 9 characters plus the nul, so 10 all together. The longest string is "Wednesday." The buffer of temp is set to 10, which should in theory be enough. Could I be reading the file incorrectly? – Chris Jan 20 '18 at 04:14
  • "Wednesday." with a period? Using the debugger, check the value for unexpected characters. – 1201ProgramAlarm Jan 20 '18 at 04:15
  • @1201ProgramAlarm My apologies, the period is not included in the string. I just ran the debugger and found that it is testing a string with a string of "ÌÌÌÌÌÌÌÌÌÌ..." (periods included this time). I have no idea where this is coming from. – Chris Jan 20 '18 at 04:22
  • When you are doing `strcmp(days[j - 1], days[j])` at the first iteration of the nested `for` loop in `sort_Days`, you are trying to index `days[-1]`, which is not what you want in C++ as indexing doesn't 'wrap around'. – L.Y. Sim Jan 20 '18 at 04:37
  • @L.Y.Sim What would be the correct way to do that then? – Chris Jan 20 '18 at 04:43
  • I'll look through your code and provide an answer if I can. – L.Y. Sim Jan 20 '18 at 04:49

1 Answers1

2

A few things are wrong with the code:

sort_Days

The sort_Days algorithm is throwing errors because you are trying to index days[j - 1] when the nested for loop starts with j = 0. So your initial index is out of bounds.

Furthermore, it seems like you are trying to perform bubble sort on the c-style strings, but your bubble sort implementation is incorrect. Please consult this page for how to implement a simple bubble sort. Hint: the for loop conditional, strcmp and strcpy_s indices need some tweaking.


print_Days

Your print_Days function is incorrect. Here is a version that prints out each c-style string instead of each char within the string:

void print_Days(const char days[][NUM_OF_COLS], const int rows) 
{
    for (int j = 0; j < rows; j++)
    {
        cout << days[j] << endl;
    }
}

You should know that std::cout understands that when you pass it a c-style string (i.e. the char[NUM_OF_COLS] within days), it means you want to print out the whole string up to the null-terminator.

Your for loop termination conditional was also wrong, because you had j < NUM_OF_COLS, whereas days actually is an array with NUM_OF_ROWS elements, and each element is an array of NUM_OF_COLS size. The way you had it had indexing out of bounds of the days array.


And while I am nitpicking

Try not to use using namespace::std;, there are plenty of reasons why you shouldn't..

L.Y. Sim
  • 810
  • 6
  • 11