I'm trying to write a program that takes Roman numerals as input and then converts them to decimal values. The user has to first declare how many Roman numerals they are going to input (either one or two).
I am using a for loop that repeats as many times as the number of Roman numerals. It either shouldn't loop if the there is only one numeral or if there are two it should loop twice because we need to take one letter as input at a time.
The issue I was having is that the scanf statement that is inside the for loop, keeps preventing the programme from looping. As soon as I removed the scanf and statically assigned the value then it worked perfectly fine. Then while trying to fix the issue I tried to print out the value scanf is returning by assigning it to a new variable, like char snf = scanf("%s", &numeral);
and for some reason it started working exactly I wanted it to work. I have absolutely no idea why it is working now and why it was preventing the loop from looping before. Can anyone explain to me what's going on?
// A program to convert Roman Numerals to Decimals system.
#include <stdio.h>
int convert_numerals(char numeral){
switch(numeral){
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
default :
printf("\nError! You did not enter a valid numeral\n");
return 0;}}
int main(){
int Decimal_Val = 0; //Initializing the variable with 0 to avoid issues at check.
int Numeral_Count;
printf("How many characters does your Roman numerals have? 1 or 2\n");
scanf("%d",&Numeral_Count);
for (int i = 1; i < 1 Numeral_Count; i)
{
char numeral = 'O';
int converted_val;
printf("\n\nEnter numeral %d : ",i);
scanf("%s", &numeral); // The problematic line.
converted_val = convert_numerals(numeral);
if (Decimal_Val != 0)
{
if (Decimal_Val < converted_val)
{
Decimal_Val = converted_val - Decimal_Val;
}else{
Decimal_Val = converted_val;
}
}else{
Decimal_Val = converted_val;
}
}
printf("\nThe Roman numerals you entered are equal to %d in Decimals\n", Decimal_Val);
return 0;
}
CodePudding user response:
Scanf can be a problematic function, especially with characters. Instead, try using fgets
to read a line, then use the first character. If we break this out into a separate function. (Breaking problems down is crucial to solving complex problems in any programming language.)
char get_roman_numeral(const char *prompt, const char * error_msg) {
while (1) {
printf("%s: ", prompt);
char input[20] = {};
fgets(input, 19, stdin);
input[strcspn(input, "\n")] = '\0';
if (strlen(input) > 0) {
switch (input[0]) {
case 'i': case 'I':
case 'v': case 'V':
case 'x': case 'X':
case 'l': case 'L':
case 'c': case 'C':
case 'd': case 'D':
case 'm': case 'M':
return input[0];
default:
printf("%s\n", error_msg);
}
}
else {
printf("%s\n", error_msg);
}
}
}
Picking this apart, we loop indefinitely. Each time we print the prompt we provide, then read a line from stdin
into the char buffer input
which can hold 20 characters (one of them has to be the null terminating character).
input[strcspn(input, "\n")] = '\0';
This is going to find the first newline character in the input string and set it to '\0'
. This effectively removes the newline character than fgets
will include in the input string.
If the input string is then longer than 0 characters, we'll evaluate the first character. If it's a roman numeral, we return it. The function is done!
If it's either not a roman numeral, or the string is zero characters in length, we'll print the error message, and the loop starts over.
Hopefully looking at getting your input this way, without the problematic scanf
will help you solve the bigger problem.
CodePudding user response:
just decide to stop working for no apparent reason.
Below fails as "%s"
attmeps to form a string and numeral
is only big enoguh for the stirng ""
.
//char numeral = 'O';
//scanf("%s", &numeral); // The problematic line.
char numeral[100];
if (scanf("