Hello,

I've nearly finished writing a program that converts Roman to arabic numbers, but i've run into a problem to do with the "Batch Mode" of the program.

The batch mode involves asking the user to type in the file name (a text file) which contains Roman numerals that need to be converted by the program. After reading the filename, it is supposed to open and read it.
For some reason, everytime i type in the filename to be scanned in and read, an assertion error appears. Now i have only been working for C++ for a little over a month, but i cant identify the error.

What am i doing wrong?
a snippet of the code i'm using for the 'Batch Mode':

//BATCH CONVERSION//

	else if(menu_select==2)
	{	
		char romNum [80];
		char fileName[80];
		FILE * file_numerals;


		printf ("-------------------------------------\n");
		printf ("-------- 2. BATCH CONVERSION --------\n");
		printf ("-------------------------------------\n");
		printf ("\nPlease type the name of the file you want to open below.\nName(including suffix): ");

		scanf ("%s", &fileName);

  file_numerals = fopen (("%s", fileName),"r");
  rewind (file_numerals);

while (!feof(file_numerals));
	{
		fscanf (file_numerals, "%s", &romNum);
	}

  fclose (file_numerals);
  printf ("You have chosen to convert the following characters: %s \n",romNum);
  int roman;
  
  return 0;

}

Thanks to anyone who can help me.

>>file_numerals = fopen (("%s", fileName),"r");
The first parameter to fopen is NOT a format string like printf() but the filename. How did you even get this program to compile without any errors anyway????? Here is how it should be: file_numerials = fopen(filename, "r");

while (!feof(file_numerals));
{
fscanf (file_numerals, "%s", &romNum);
}

That's the wrong loop and won't work the way you think it will. I assume you want to read the file one word at a time instead of a whole line at a time. And you do NOT use the '&' symbol in front of the variable name because romNum is passed by reference (or pointer) by default.

while( fscanf (file_numerals, "%s", romNum) > 0)
{
    // do something
}

>>file_numerals = fopen (("%s", fileName),"r");
The first parameter to fopen is NOT a format string like printf() but the filename. How did you even get this program to compile without any errors anyway????? Here is how it should be: file_numerials = fopen(filename, "r");

Thanks, I tried that code just now, it compiled, but its still giving me an assertion error. Theres probably a major flaw in the way im writing this part of the program, but I don't know where I'm going wrong.

Post the whole program so that I can take a look at it.

>> rewind (file_numerals);
That isn't necessary after the open statement because the file pointer is set to the beginning of the file when it is opened (this behavior can be changed depending on some of the other open flags)

Post the whole program so that I can take a look at it.

>> rewind (file_numerals);
That isn't necessary after the open statement because the file pointer is set to the beginning of the file when it is opened (this behavior can be changed depending on some of the other open flags)

Ok, here it is so far. Sorry for all the comments.

#include <stdio.h>
#include <string.h>	
#include <stdlib.h>
//Extra '#include's needed because the tasks involve advanced activities, such as opening streams and using strings.//

int roman (const char* );	
	//This is the prototype of the 'roman' function, which handles the mathematics needed for the conversion.//
	//The 'char*' allows the user to type in as many numerals as the computer's memory can hold.//

int main()

	
{
	int menu_select=0;
	
	//This is the function that allows the user to choose between normal conversion mode or batch mode.//
	//It is set to zero before the user inputs a '1' or a '2'; this ensures the program does not make an unauthorised choice.//

	//Introduction to the program.//
	printf ("WRITTEN & TESTED BY SEMY INGLE\nCOMPLETED: 09/12/07\n\n");
	printf ("-------------------------------------\n");
	printf ("--- The ROMAN To ARABIC Converter ---\n");
	printf ("-------------------------------------\n");
	printf ("\nINTRODUCTION\nWelcome to the 'roman numerals to arabic numbers' converter.\nThis program will allow you to to do either of two things:\n\n");
	printf ("1.  Convert roman numerals that you type in, into arabic numbers;\n2.  Read roman numerals from a file, convert them, and write the converted\n numbers to a new text document.\n\n");
	printf ("The roman numerals supported in this program (and their arabic equivalents) are listed below.\nPlease use only the characters listed, or the conversion will fail:\n\n");
	printf ("  I - 1\n  V - 5\n  X - 10\n  L - 50\n  C - 100\n  D - 500\n  M - 1000\n\n");
	printf ("NOTE\nThis program does not convert arabic numbers to roman numerals.\n\n");

	{
		printf ("-------------------------------------\n");
		printf ("------------- MAIN MENU -------------\n");
		printf ("-------------------------------------\n");
		printf("\nPlease choose one of the following modes of conversion, by typing the number\n     associated with it.\n\n  1.  Instant Conversion\n  2.  Batch Mode\n");
		printf("\nChoice: ");
		scanf("%i",&menu_select);
		printf("\n");
	}



	//INSTANT ROMAN TO ARABIC CONVERISON//

	if(menu_select==1)
	{  
		char romNum [BUFSIZ] = {0}; //variable rom defined as a stribg of characters ,BUFSIZ=size of the stdio buffers, allows the user to enter as many numerals as the computer can handle//

		printf ("-------------------------------------\n");
		printf ("------ 1. INSTANT CONVERSION --------\n");
		printf ("-------------------------------------\n");
		printf("\nReferring to the list of accepted Roman numerals if needed, please type in\nyour numerals for conversion.\n\nROMAN NUMERALS: "); //user asked to enter roman numberals in the form of a //
		scanf("%i",&romNum);//string is scanned in by the programme//
		
		fgets( romNum, BUFSIZ, stdin );  //string is read over here//
		romNum[ strlen( romNum )-1 ] = '\0';
		printf("\n\nARABIC NUMBERS: %d\n\n", roman (romNum) );//arabic value is printed //
	}


	
	//BATCH CONVERSION//

	else if(menu_select==2)
	{	
		char romNum [80];
		char fileName[80];
		FILE * file_numerals;


		printf ("-------------------------------------\n");
		printf ("-------- 2. BATCH CONVERSION --------\n");
		printf ("-------------------------------------\n");
		printf ("\nPlease type the name of the file you want to open below.\nName(including suffix): ");

		scanf ("%s", &fileName);

  file_numerals = fopen(fileName, "r");
  rewind (file_numerals);

while (!feof(file_numerals));
	{
		fscanf (file_numerals, "%s", &romNum);
	}

  fclose (file_numerals);
  printf ("You have chosen to convert the following characters: %s \n",romNum);
  int roman;
  
  return 0;

}


	else
	{
		printf("Incorrect number.\n");// //	
	}

 return 0;
	
}




int roman (const char* romNum)//function//
{
    int value = 0; //current value//
	int total = 0;	//total number of values//
    int prev = 5000; //previous value//  
    
	
	while( *romNum )
    {
		switch (*romNum)
		{
		case 'i':
		case 'I':
		value = 1;
		break;
		
		case 'v':
		case 'V':
		value = 5;
		break;
		
		case 'x':
		case 'X':
		value = 10;
		break;
		
		case 'l':
		case 'L':
		value = 50;
		break;
		
		case 'c':
		case 'C':
		value = 100;
		break;
		
		case 'd':
		case 'D':
		value = 500;
		break;
		
		case 'm':
		case 'M':
		value = 1000;
		break;
		default:
		
		printf("You have typed an invalid Roman Numeral. Please use the characters listed above.");
		break;
    }


    if( prev >= value )  //if the previous value is more than the current value then add it to the total//
	{
	    total += value;
	}
	else // prev < value//
	{
	    total += (value - (prev + prev)); //if the previous value is less than the current value subrtace the current value from the previous//
	}
	prev = value;
	++romNum;// end of lood, tells programme to go to the next character//
    }
    return total;
}

>>while (!feof(file_numerals));

That is an infinite loop! code it like I posted previously or remove the semicolon at the end of that line.

you also need to add a check that the file was opened ok.

>>while (!feof(file_numerals));

That is an infinite loop! code it like I posted previously or remove the semicolon at the end of that line.

Ok i sort of changed it a different way (after trying your suggested code), but both come up with an assertion error. The error seems to mention the first thing after the scanf statement.
When you said //do something, what was it exactly that you meant? I don't know if i explained it well initially, but that part is meant to add another line to the string and move to the next line until the end of the file.

Ok don't worry I cracked it, your code did the job, it was something to do with the file itself it was trying to read.

I still have two problems though,
1. the file i'm reading from has more than one line of roman numerals in it, but only the last line is displayed by the printf;
2. how can i get those characters that have just been read in the file, and convert them the same way as is done in the "instant conversion" part of my program?

>>your code did the job, it was something to do with the file itself it was trying to read.
It had nothing at all to do with the file -- the problem was your code was wrong.

>> the file i'm reading from has more than one line of roman numerals in it, but only the last line is displayed by the printf;
Yes I saw that too. If you want to display all of them then put the print statement inside the loop.

>>how can i get those characters that have just been read in the file, and convert them the same way as is done in the "instant conversion" part of my program
It should be obvious -- do it the same way that you did before by calling that function inside the loop.

>>your code did the job, it was something to do with the file itself it was trying to read.
It had nothing at all to do with the file -- the problem was your code was wrong.

>> the file i'm reading from has more than one line of roman numerals in it, but only the last line is displayed by the printf;
Yes I saw that too. If you want to display all of them then put the print statement inside the loop.

>>how can i get those characters that have just been read in the file, and convert them the same way as is done in the "instant conversion" part of my program
It should be obvious -- do it the same way that you did before by calling that function inside the loop.

Wow, I've done it, thank you so much! Had to do a bit of tweeking though. Heres my final code for the batch mode:

printf ("\nPlease type the name of the file you want to open below.\nName(including suffix): ");

		scanf ("%s", &fileName);

	file_numerals = fopen(fileName, "r");
	printf ("You have chosen to convert the following characters: \n\n");
 
	while( fscanf (file_numerals, "%s", romNum) > 0)

{
    printf ("%s \n",romNum);
	romNum[ strlen( romNum ) ] = '\0';
	printf("\ARABIC NUMBERS: %d\n\n", roman (romNum) );
}

  fclose (file_numerals);
  
}

>>romNum[ strlen( romNum ) ] = '\0';
That line is not necessary when using fscanf(). Only need it with fgets(). If you use it with fscanf() you will chop off the right-most letter in the roman numerial

>>romNum[ strlen( romNum ) ] = '\0';
That line is not necessary when using fscanf(). Only need it with fgets(). If you use it with fscanf() you will chop off the right-most letter in the roman numerial

Yeah i noticed that, i had to get rid of the 'minus 1' bit after (romNum), that seemed to solve it. Thanks anyway. Seems more ecological your way.

This article has been dead for over six months. Start a new discussion instead.