Not allowed because they have the same name but different parameters. Valid in C++, but not C.Code:void initialise (char []);
void initialize (int []);
Not allowed because they have the same name but different parameters. Valid in C++, but not C.Code:void initialise (char []);
void initialize (int []);
Also I need a file read in or input from keyboard - and could not figure out how to do it without duplicating the code with a massive if???
Not sure what you're hinting at?
It is very bad to use subtle differences in function names (such as "initialize" and "initialise"). It is almost impossible to see the difference without reading each individual letter. If you want to make two functions different, use prefix or postfix, e.g.
For example:
orCode:InitializeInt();
InitializeChar();
As Elysia says, using either:Code:CharInitialize();
IntInitialize();
orCode:int count[16] = { 0 };
would be much better.Code:memset(count, 0, sizeof(count));
[Don't use ZeroMemory, that is a windows specifc function, and you only want to use such functions when the entire file only contains windows-specific code]
Not to mention that your code in initialize is broken:
You have 13 elements, but you initialize 16.Code:int count [13];
void initialize (int tab[])
{
int i;
for (i=0; i<=15; ++i)
tab[i] = 0;
}
--
Mats
Many thanks for all your help. I have decided to steer clear of functions - don't understand parsing/passing well enough yet...
What I have done seems to work, although it is more scrappy... The only thing that doesn't work is reading the file in but I don't not whether thats how its being executed or the code.
Many thanks for all your help. When I get a little better and can help others I surely will...
Code:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char tab[16];
int REP;
int i;
int z;
int total;
int c;
int unreal = 0;
FILE *file_in;
FILE *file_out;
int CountM, CountD, CountC, CountL, CountX, CountV, CountI, CountCM, CountCD, CountXC, CountXL, CountIX, CountIV;
CountM = CountD = CountC = CountL = CountX = CountV = CountI = CountCM = CountCD = CountXC = CountXL = CountIX = CountIV = 0;
for (z=0; z<=15; ++z)
{
tab[z] = 0;
}
printf("\nChoose 1 for FILE input");
printf("\nChoose 2 for KEYBOARD input: ");
do
{
scanf("%i", &c);
}
while ((c <=0) || (c >=3));
if (c == 1)
{
printf("You have chosen one - file input"); //STILL NEED TO FIGURE OUT CODE TO INPUT A STRING VIA A FILE
{
file_in = fopen("Roman.txt","r");
fscanf(file_in, "%s", tab);
fclose(file_in);
return 0;
}
}
else if (c == 2)
{
printf("You have chosen two - file input"); // (KEYBOARD MODE) ASK FOR NUMERALS AND COPY INTO "LETTERS"
printf("\nPlease input your ROMAN NUMERALS from the keyboard: ");
scanf("%s", tab);
}
for (i=0; tab[i] != '\0';i++)
switch (tab[i])
{
case 'M':
REP = 4;
CountM ++;
if (CountM > REP)
{
printf("ERROR: You have input too many M's");
unreal = 1;
}
break;
case 'D':
REP = 1;
CountD ++;
if (CountD > REP)
{
printf("ERROR: You have input too many D's");
unreal = 1;
}
break;
case 'C':
i++;
REP = 3;
CountC ++;
if (CountC > REP)
{
printf("ERROR: You have input too many C's");
unreal = 1;
}
REP = 1;
switch (tab[i])
{
case '\0':
break;
case 'M':
i++;
CountC --; CountCM ++;
if (CountCM > REP)
{
printf("ERROR: You have input too many CM's");
unreal = 1;
}
break;
case 'D':
i++;
CountC --; CountCD ++;
if (CountCD > REP)
{
printf("ERROR: You have input too many CD's");
unreal = 1;
}
break;
}i --;
break;
case 'L':
REP = 1;
CountL ++;
if (CountL > REP)
{
printf("ERROR: You have input too many L's");
unreal = 1;
}
break;
case 'X':
i++;
REP = 3;
CountX ++;
if (CountX > REP)
{
printf("ERROR: You have input too many X's");
unreal = 1;
}
REP = 1;
switch (tab[i])
{
case '\0':
break;
case 'C':
i++;
CountX -- ; CountXC ++;
if (CountXC > REP)
{
printf("ERROR: You have input too many XC's");
unreal = 1;
}
break;
case 'L':
i++;
CountX -- ; CountXL ++;
if (CountXL > REP)
{
printf("ERROR: You have input too many XL's");
unreal = 1;
}
break;
}i--;
break;
case 'V':
REP = 1;
++ CountV;
if (CountV > REP)
{
printf("ERROR: You have input too many V's");
unreal = 1;
}
break;
case 'I':
i++;
REP = 3;
++ CountI;
if (CountI > REP)
{
printf("ERROR: You have input too many I's");
unreal = 1;
}
REP = 1;
switch (tab[i])
{
case '\0':
break;
case 'X':
i++;
CountI -- ; CountIX ++ ;
if (CountIX > REP)
{
printf("ERROR: You have input too many IX's");
unreal = 1;
}
break;
case 'D':
i++;
CountI --; CountIV ++ ;
if (CountIV > REP)
{
printf("ERROR: You have input too many IV's");
unreal = 1;
}
break;
}i--;
break;
default:
printf("You have input an invalid character");
}
//CALCULATE THE TOTAL OF ALL THE COUNTS MULTIPLIED AGAINST THEIR EQUIVALENT ARABIC VALUE
total = ((CountM*1000) + (CountD*500) + (CountC*100) + (CountL*50) + (CountX*10)
+ (CountV*5) + (CountI) + (CountCM*900) + (CountCD*400) + (CountXC*90) + (CountXL*40)
+ (CountIX*9) + (CountIV*4));
if (c == 1)
{
printf("You have chosen one - file input"); //STILL NEED TO FIGURE OUT CODE TO INPUT A STRING VIA A FILE
{
file_out = fopen("new.txt","w");
fprintf(file_out, "%i", total);
fclose(file_out);
return 0;
}
}
//PRINT THE ORIGINAL ROMAN NUMERAL AND THE ARABIC CONVERTED VALUE
printf("\n The value you input in ROMAN NUMERALS was: %s", tab);
if (unreal == 0)
printf("\n The equivalent value in Arabic numbers is: %i", total);
else
printf("\n The possible equivalent value of your BADLY CONSTRUCTED ROMAN NUMERAL in Arabic numbers is: %i", total);
}
Steer clear of functions is probably not really the right approach. That's like saying "because using a hammer to fit a piece of glass broke the glass, I won't use a hammer ever again".
Using the right tool for the job is what it's all about. Functions are great for splitting a task into smaller sections.
Learning how to split a task into smaller sections is all part of programming.
Your code as it stands now is a bit too complex, in my opinion. You could certainly make it better by splitting it up.
In this case, you could also use a table that contains the single or multiple letters [e.g. C, M, IX, CM, etc], the repeat count, and the value for that particlar piece of roman numbers, and then use that table to parse the number, instead of your huge switch statement. Just make sure you check for CM and such before you look for C [simply done by placing those earlier in the table than the "plain" digits].
--
Mats
Don't use fscaf for reading strings - it's unsafe. Use fgets instead.
As for reading/writing to files, you're getting there. Remember to check for NULL in your stream returned by fopen. If fopen fails and you call another function, your program will crash trying to read memory from NULL (which will crash on any x86 system).
When reading, once again, use fgets. When writing, you can use fputs (saves a string to the stream).
Could you possibly give me a small example of how I might set up such a table as I haven't yet covered them. I had a look at them but got a bit confused. Maybe if you are unable to give an example you could possibly give me a link to some more information on the subject... with examples
Many thanks again.
And thanks Elysia I am looking into fgets...
--Code:struct RomanValue
{
std::string num;
int value;
int maxRep;
};
RomanValue romanValues[] =
{
{"CM", 900, 1 },
{ "M", 1000, 4 },
{ "C", 100, 3 },
....
};
Mats