Assertion Errors

I

inkexit

I'm getting assertion errors when I try to import or export a file
using this code. Please help. I don't even know what an assertion
error is.

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

const int MAX_SIZE = 50;

struct widget
{
char color;
int size;
float weight;
string material;
};

widget my_widget[MAX_SIZE];

void import_db(widget my_widget[MAX_SIZE], ifstream *input_file, int
*num_items)
{
int i = 0;
*num_items = 0;
while( !(*input_file).eof())
{
*input_file >> my_widget.color >> my_widget.size;
*input_file >> my_widget.weight >> my_widget.material;

//must check for EOF
if( !(*input_file).eof())
{
i++;
}
}
*num_items = i;
}

void export_db(widget my_widget[MAX_SIZE], ofstream *out_file, int
num_items)
{
int i;
for (i=0; i<num_items; i++)
{
(*out_file) << my_widget.color << my_widget.size <<
my_widget.weight << my_widget.material << endl;
}
}

void print_db(widget my_widget[MAX_SIZE], int *num_items)
{
for(int i=0; i < *num_items; i++)
{
cout << setiosflags(ios::left);
cout << setw(8) << my_widget.color << setw(6) <<
my_widget.size;
cout << setw(9) << my_widget.weight << setw(9) <<
my_widget.material << endl;
}
}

void add_item(widget my_widget[MAX_SIZE], widget *item, int *num_items)

{

//if user wants to add an item when the array is full, exit
if (*num_items >= MAX_SIZE)
{
cout << "\nSorry, too many items are in the database already.";
cout << "\nProgram now exiting...";
exit (1);
}
else
{
//add item struct to my_widget
my_widget[*num_items].color = (*item).color;
my_widget[*num_items].size = (*item).size;
my_widget[*num_items].weight = (*item).weight;
my_widget[*num_items].material = (*item).material;
(*num_items)++;
}
}

void del_item(widget my_widget[MAX_SIZE], int item_num, int *num_items)

{
int i;
//shift all items > item_num, up one position in my_widget
for (i=(item_num-1); i<*num_items-1; i++)
{
my_widget = my_widget[i+1];
}
(*num_items)--;
}

int main()
{
//declare my_widget and program variables
ofstream out_file;
ifstream input_file;
widget item;
char operation_choice = 'x', modify_choice, color_choice;
int size_choice, num_items = 0, item_num;
float weight_choice;
string material_choice, file_name;

//main switch statement of the program
//this is where all user interaction occurs
//this loop while continue until the user exits
do
{
cout << "\nDatabase operations: \ni) import database \ne) export
database";
cout << "\np) print database \nm) modify database \nq) quit \nChoice:
";

cin >> operation_choice;

switch (operation_choice)
{
case 'i':
{
//user chooses import
do
{
cout << "\nEnter the name of the file to import: ";
//grab the filename
getline(cin, file_name);
cin.ignore(INT_MAX,'\n');
//try to open the file
input_file.open(file_name.c_str());
}while(!input_file);


import_db(my_widget, &input_file, &num_items);

//close file
//from now on, all operations done on my_widget array in local
memory
input_file.close();
break;
}

case 'e':
{
//user chooses to export
cout << "\nEnter the name of the file to export: ";
//grab the filename
getline(cin, file_name);
cin.ignore(INT_MAX,'\n');
//open the file to write to
out_file.open(file_name.c_str());
//export my_widget using export_db function
export_db(my_widget, &out_file, num_items);
//close file
out_file.close();
break;

}

case 'p':
{

//user chooses to print, print my_widget
print_db(my_widget, &num_items);
break;
}

case 'm':
{

//user chooses to modify my_widget
cout << "\n(A)dd or (D)elete an item? ";
cin >> modify_choice;
cin.ignore(INT_MAX,'\n');

if (modify_choice == 'a' || modify_choice == 'A')
{
//user chooses to add an item. prompt user for data.
cout << "Color? ";
cin >> color_choice;
cin.ignore(INT_MAX,'\n');
cout << "Size? ";
cin >> size_choice;
cin.ignore(INT_MAX,'\n');
cout << "Weight? ";
cin >> weight_choice;
cin.ignore(INT_MAX,'\n');
cout << "Material? ";
cin >> material_choice;
cin.ignore(INT_MAX,'\n');

//store all the new info in a widget struct called item
item.color = color_choice;
item.size = size_choice;
item.weight = weight_choice;
item.material = material_choice;

//add new item to my_widget using add_item function.
add_item(my_widget, &item, &num_items);
}
else
{
//user chooses to delete an item, prompt user for the
//number of the item to delete.
cout << "Enter the item number to delete: ";
cin >> item_num;
cin.ignore(INT_MAX,'\n');

//actually delete the item from my_widget by using del_item
function
del_item(my_widget, item_num, &num_items);
}
break;
}
case 'q':
{

//user chooses to quit, quit program
cout << "exiting program...";
exit (1);
break;
}
}
}
while ( operation_choice != 'q' ); //if user does not choose to exit
//continue to ask user to do operations


return 0;
}
 
M

mlimber

I'm getting assertion errors when I try to import or export a file
using this code. Please help. I don't even know what an assertion
error is.

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

const int MAX_SIZE = 50;

struct widget
{
char color;
int size;
float weight;
string material;
};

widget my_widget[MAX_SIZE];

void import_db(widget my_widget[MAX_SIZE], ifstream *input_file, int
*num_items)
{
int i = 0;
*num_items = 0;
while( !(*input_file).eof())
{
*input_file >> my_widget.color >> my_widget.size;
*input_file >> my_widget.weight >> my_widget.material;

//must check for EOF
if( !(*input_file).eof())
{
i++;
}
}
*num_items = i;
}

void export_db(widget my_widget[MAX_SIZE], ofstream *out_file, int
num_items)
{
int i;
for (i=0; i<num_items; i++)
{
(*out_file) << my_widget.color << my_widget.size <<
my_widget.weight << my_widget.material << endl;
}
}

void print_db(widget my_widget[MAX_SIZE], int *num_items)
{
for(int i=0; i < *num_items; i++)
{
cout << setiosflags(ios::left);
cout << setw(8) << my_widget.color << setw(6) <<
my_widget.size;
cout << setw(9) << my_widget.weight << setw(9) <<
my_widget.material << endl;
}
}

void add_item(widget my_widget[MAX_SIZE], widget *item, int *num_items)

{

//if user wants to add an item when the array is full, exit
if (*num_items >= MAX_SIZE)
{
cout << "\nSorry, too many items are in the database already.";
cout << "\nProgram now exiting...";
exit (1);
}
else
{
//add item struct to my_widget
my_widget[*num_items].color = (*item).color;
my_widget[*num_items].size = (*item).size;
my_widget[*num_items].weight = (*item).weight;
my_widget[*num_items].material = (*item).material;
(*num_items)++;
}
}

void del_item(widget my_widget[MAX_SIZE], int item_num, int *num_items)

{
int i;
//shift all items > item_num, up one position in my_widget
for (i=(item_num-1); i<*num_items-1; i++)
{
my_widget = my_widget[i+1];
}
(*num_items)--;
}

int main()
{
//declare my_widget and program variables
ofstream out_file;
ifstream input_file;
widget item;
char operation_choice = 'x', modify_choice, color_choice;
int size_choice, num_items = 0, item_num;
float weight_choice;
string material_choice, file_name;

//main switch statement of the program
//this is where all user interaction occurs
//this loop while continue until the user exits
do
{
cout << "\nDatabase operations: \ni) import database \ne) export
database";
cout << "\np) print database \nm) modify database \nq) quit \nChoice:
";

cin >> operation_choice;

switch (operation_choice)
{
case 'i':
{
//user chooses import
do
{
cout << "\nEnter the name of the file to import: ";
//grab the filename
getline(cin, file_name);
cin.ignore(INT_MAX,'\n');
//try to open the file
input_file.open(file_name.c_str());
}while(!input_file);


import_db(my_widget, &input_file, &num_items);

//close file
//from now on, all operations done on my_widget array in local
memory
input_file.close();
break;
}

case 'e':
{
//user chooses to export
cout << "\nEnter the name of the file to export: ";
//grab the filename
getline(cin, file_name);
cin.ignore(INT_MAX,'\n');
//open the file to write to
out_file.open(file_name.c_str());
//export my_widget using export_db function
export_db(my_widget, &out_file, num_items);
//close file
out_file.close();
break;

}

case 'p':
{

//user chooses to print, print my_widget
print_db(my_widget, &num_items);
break;
}

case 'm':
{

//user chooses to modify my_widget
cout << "\n(A)dd or (D)elete an item? ";
cin >> modify_choice;
cin.ignore(INT_MAX,'\n');

if (modify_choice == 'a' || modify_choice == 'A')
{
//user chooses to add an item. prompt user for data.
cout << "Color? ";
cin >> color_choice;
cin.ignore(INT_MAX,'\n');
cout << "Size? ";
cin >> size_choice;
cin.ignore(INT_MAX,'\n');
cout << "Weight? ";
cin >> weight_choice;
cin.ignore(INT_MAX,'\n');
cout << "Material? ";
cin >> material_choice;
cin.ignore(INT_MAX,'\n');

//store all the new info in a widget struct called item
item.color = color_choice;
item.size = size_choice;
item.weight = weight_choice;
item.material = material_choice;

//add new item to my_widget using add_item function.
add_item(my_widget, &item, &num_items);
}
else
{
//user chooses to delete an item, prompt user for the
//number of the item to delete.
cout << "Enter the item number to delete: ";
cin >> item_num;
cin.ignore(INT_MAX,'\n');

//actually delete the item from my_widget by using del_item
function
del_item(my_widget, item_num, &num_items);
}
break;
}
case 'q':
{

//user chooses to quit, quit program
cout << "exiting program...";
exit (1);
break;
}
}
}
while ( operation_choice != 'q' ); //if user does not choose to exit
//continue to ask user to do operations


return 0;
}


Assertions are used to document the assumptions of the programmer. For
instance, you might have a function:

#include <cassert>

void Foo( int *const pi )
{
assert( 0 != pi );
*pi = 42;
}

This function requires that pi not be null on entry, and if the
assertion fails, the program terminates or something to that effect.

Where are you getting the error? What is the input sequence you use to
reproduce the problem?

Probably a pointer is null somewhere. Step through the code in your
debugger or add some extra print statements to identify which line(s)
cause the problem.

Cheers! --M
 
H

Howard

I'm getting assertion errors when I try to import or export a file
using this code. Please help. I don't even know what an assertion
error is.

Assertion failures occur when an assert statement tests an statement which
returns false, such as:

assert (n > 0);

when n is actually 0 (or less, if unsigned).

Assert statements are used in debug (development) versions of software to
let you know you've got a design problem, such as allowing invalid data
(n==0) to be passed to a function that absolutely _requires_ valid data (n >
0).


You need to find _where_ in the code that assertion is raised. If the error
message you're seeing doesn't give you enough information to find it, then
use your debugger to find where it happens.

I do see one line that doesn't make sense to me (although I admit I'm not
up-to-date on streams):

do
{
....
//try to open the file
input_file.open(file_name.c_str());
}while(!input_file);

Shouldn't the test be whether input_file.open() succeeds or not?

One other thing I see in your code: you're using exit(1) when the user tries
to enter an item there's no room left for. That's not a clean way to handle
user errors at all. Why not let the user know they tried to do something
wrong, and simply prevent that specific action from doing anything? Why
crash the application?

-Howard
 
I

inkexit

Okay, well I tried to run the visual studio debugger and it gave me
this .c file. I'm in way over my head here. I assume this is some
higher level code the compiler translates my .cpp fil into?

Anyway, the debugger said the erros is being caused by line 55. I have
added a comment to that line for easy identification.



/***
*fopen.c - open a file
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines fopen() and _fsopen() - open a file as a stream and
open a file
* with a specified sharing mode as a stream
*
*******************************************************************************/

#include <cruntime.h>
#include <stdio.h>
#include <share.h>
#include <dbgint.h>
#include <internal.h>
#include <mtdll.h>
#include <file2.h>
#include <tchar.h>
#include <errno.h>

/***
*FILE *_fsopen(file, mode, shflag) - open a file
*
*Purpose:
* Opens the file specified as a stream. mode determines file
mode:
* "r": read "w": write "a": append
* "r+": read/write "w+": open empty for read/write
* "a+": read/append
* Append "t" or "b" for text and binary mode. shflag determines
the
* sharing mode. Values are the same as for sopen().
*
*Entry:
* char *file - file name to open
* char *mode - mode of file access
*
*Exit:
* returns pointer to stream
* returns NULL if fails
*
*Exceptions:
*
*******************************************************************************/

FILE * __cdecl _tfsopen (
const _TSCHAR *file,
const _TSCHAR *mode
,int shflag
)
{
REG1 FILE *stream;
REG2 FILE *retval;

_ASSERTE(file != NULL);
_ASSERTE(*file != _T('\0')); /*THE ERROR IS WITH THIS LINE*/
_ASSERTE(mode != NULL);
_ASSERTE(*mode != _T('\0'));

/* Get a free stream */
/* [NOTE: _getstream() returns a locked stream.] */

if ((stream = _getstream()) == NULL) {
errno = EMFILE;
return(NULL);
}

#ifdef _MT
__try {
#endif /* _MT */

/* open the stream */
#ifdef _UNICODE
retval = _wopenfile(file,mode,shflag,stream);
#else /* _UNICODE */
retval = _openfile(file,mode,shflag,stream);
#endif /* _UNICODE */

#ifdef _MT
}
__finally {
_unlock_str(stream);
}
#endif /* _MT */

return(retval);
}


/***
*FILE *fopen(file, mode) - open a file
*
*Purpose:
* Opens the file specified as a stream. mode determines file
mode:
* "r": read "w": write "a": append
* "r+": read/write "w+": open empty for read/write
* "a+": read/append
* Append "t" or "b" for text and binary mode
*
*Entry:
* char *file - file name to open
* char *mode - mode of file access
*
*Exit:
* returns pointer to stream
* returns NULL if fails
*
*Exceptions:
*
*******************************************************************************/

FILE * __cdecl _tfopen (
const _TSCHAR *file,
const _TSCHAR *mode
)
{
return( _tfsopen(file, mode, _SH_DENYNO) );
}
 
I

inkexit

Yes. That is a good point. But I couldn't figure out how to break out
of a switch statement from a an if statement nested within it.
 
V

Victor Bazarov

Okay, well I tried to run the visual studio debugger and it gave me
this .c file. I'm in way over my head here. I assume this is some
higher level code the compiler translates my .cpp fil into?

No, that's a library function. Look at the call stack, go to _your_
function there and see what values your variables have. IOW, learn to
use your debugger.
Anyway, the debugger said the erros is being caused by line 55. I have
added a comment to that line for easy identification.



/***
*fopen.c - open a file
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines fopen() and _fsopen() - open a file as a stream and
open a file
* with a specified sharing mode as a stream
*
*******************************************************************************/

#include <cruntime.h>
#include <stdio.h>
#include <share.h>
#include <dbgint.h>
#include <internal.h>
#include <mtdll.h>
#include <file2.h>
#include <tchar.h>
#include <errno.h>

/***
*FILE *_fsopen(file, mode, shflag) - open a file
*
*Purpose:
* Opens the file specified as a stream. mode determines file
mode:
* "r": read "w": write "a": append
* "r+": read/write "w+": open empty for read/write
* "a+": read/append
* Append "t" or "b" for text and binary mode. shflag determines
the
* sharing mode. Values are the same as for sopen().
*
*Entry:
* char *file - file name to open
* char *mode - mode of file access
*
*Exit:
* returns pointer to stream
* returns NULL if fails
*
*Exceptions:
*
*******************************************************************************/

FILE * __cdecl _tfsopen (
const _TSCHAR *file,
const _TSCHAR *mode
,int shflag
)
{
REG1 FILE *stream;
REG2 FILE *retval;

_ASSERTE(file != NULL);
_ASSERTE(*file != _T('\0')); /*THE ERROR IS WITH THIS LINE*/
[...]

Did you supply 'fopen' with an empty c-string as the file name?

fopen("", "r");

would certainly do it.

V
 
H

Howard

Yes. That is a good point. But I couldn't figure out how to break out
of a switch statement from a an if statement nested within it.

You said it yourself right there: "break". Break exits a loop or switch
statement (regardless if whether you're in a nested conditional statement).

In your future replies, please include the text to which you're replying (as
I've done here), or at least enough of it so that we know what you're
responding to, ok?

And check out the FAQ at:
http://www.parashift.com/c++-faq-lite/


-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top