So I'm I've been working with C for the very first time, and I think I'm having trouble using recursion. For instance, to return a value for a recursive call in C#, I might use return methodRecursiveCall(parameter). In C, I have this statement, which is a part of a roman numeral converter:
int convert(char *s)
{
int val = 0;
int index = 0;
int length = strlen(s);
while (length >1)
{
if (s[index] == 'I')
{
if(s[index + 1] == 'V' || s[index + 1] == 'X' || s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
{
val--;
index++;
length--;
convert(&(s[index]));
}
else
{
val++;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'V')
{
if(s[index + 1] == 'X' || s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
{
val = val - 5;
index++;
length--;
convert(&(s[index]));
}
else
{
val = val + 5;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'X')
{
if(s[index + 1] == 'C' || s[index + 1] == 'D' || s[index + 1] == 'M')
{
val = val - 10;
index++;
length--;
convert(&(s[index]));
}
else
{
val = val + 10;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'C')
{
if((s[index + 1]) == 'D' || (s[index + 1]) == 'M')
{
val = val - 100;
index++;
length--;
convert(&(s[index]));
}
else
{
val = val + 100;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'D')
{
if(s[index + 1] == 'M')
{
val = val - 500;
index++;
length--;
convert(&(s[index]));
}
else
{
val = val + 500;
index++;
length--;
convert(&(s[index]));
}
}
if (s[index] == 'M')
{
val = val + 500;
index++;
length--;
convert(&(s[index]));
}
}
return val;
}
My question specifically is about the convert(&(s[index]));, which is meant to be a recursive call. It is meant to convert an entire Roman numeral to decimal, however it only converts the first character. That is normally where I would put a 'return'. I'm not sure how to pull this off in C, however.
For this fragment from near the end:
if (s[index] == 'M')
{
val = val + 500;
index++;
length--;
convert(&(s[index]));
}
You probably want something like:
if (s[index] == 'M')
val = 1000 + convert(&s[index+1]);
You know that the M maps to 1,000; the total value will be 1000 + the value of what follows the M, which is what the expression states. Note that the parentheses around s[index+1] are not necessary.
You'll need to make similar changes throughout the code. You also need to review why you have iteration mixed in with recursion; you should use one or the other.
Note that your code doesn't seem to cover L aka 50.
Personally, I think this is not the best way to do the conversion. All else apart, it will be hard to spot that MXMC is invalid. My code uses an array of structures containing a string and the corresponding value (M and 1000; CM and 900) etc, and once one of the values has been used up (CM can only be used once; M can be used multiple times; CD can be used once; C can be used multiple times — that's coded too), then it can't appear again later. And it uses iteration rather than recursion.
Here's a moderately simple adaptation and fix to your code. It works OK for converting 'known to be valid' Roman numbers; it doesn't work well for validating them.
#include <stdio.h>
int convert(const char *s);
int convert(const char *s)
{
int val = 0;
int i = 0;
if (s[i] == '\0')
return 0;
if (s[i] == 'I')
{
if (s[i + 1] != 'I' && s[i + 1] != '\0')
val = convert(&s[i + 1]) - 1;
else
val = 1 + convert(&s[i + 1]);
}
if (s[i] == 'V')
val = 5 + convert(&s[i + 1]);
if (s[i] == 'X')
{
if (s[i + 1] == 'L' || s[i + 1] == 'C' || s[i + 1] == 'D' || s[i + 1] == 'M')
val = convert(&s[i + 1]) - 10;
else
val = 10 + convert(&s[i + 1]);
}
if (s[i] == 'L')
val = 50 + convert(&s[i + 1]);
if (s[i] == 'C')
{
if ((s[i + 1]) == 'D' || (s[i + 1]) == 'M')
val = convert(&s[i + 1]) - 100;
else
val = 100 + convert(&s[i + 1]);
}
if (s[i] == 'D')
val = 500 + convert(&s[i + 1]);
if (s[i] == 'M')
val = 1000 + convert(&s[i + 1]);
return val;
}
int main(void)
{
const struct roman
{
const char *str;
int num;
} test[] =
{
{ "I", 1 },
{ "II", 2 },
{ "III", 3 },
{ "IV", 4 },
{ "V", 5 },
{ "VI", 6 },
{ "VII", 7 },
{ "VIII", 8 },
{ "VIIII", 9 },
{ "IX", 9 },
{ "X", 10 },
{ "XI", 11 },
{ "XII", 12 },
{ "XIII", 13 },
{ "XIV", 14 },
{ "XV", 15 },
{ "XVI", 16 },
{ "XVII", 17 },
{ "XVIII", 18 },
{ "XIX", 19 },
{ "XVIIII", 19 },
{ "XX", 20 },
{ "XXI", 21 },
{ "XXX", 30 },
{ "XL", 40 },
{ "L", 50 },
{ "LXXVIII", 78 },
{ "XCVIII", 98 },
{ "IC", 99 },
{ "XCIX", 99 },
{ "C", 100 },
{ "D", 500 },
{ "M", 1000 },
{ "MMMDCCCLXXXVIII", 3888 },
{ "MDCMMCCLXIIIIII", 3666 }, // Not good for validating!
};
enum { NUM_TEST = sizeof(test) / sizeof(test[0]) };
for (int i = 0; i < NUM_TEST; i++)
{
int value = convert(test[i].str);
printf("%s %15s = %4d vs %4d\n", (value == test[i].num) ? "== PASS ==" : "!! FAIL !!",
test[i].str, value, test[i].num);
}
return 0;
}
Sample output:
== PASS == I = 1 vs 1
== PASS == II = 2 vs 2
== PASS == III = 3 vs 3
== PASS == IV = 4 vs 4
== PASS == V = 5 vs 5
== PASS == VI = 6 vs 6
== PASS == VII = 7 vs 7
== PASS == VIII = 8 vs 8
== PASS == VIIII = 9 vs 9
== PASS == IX = 9 vs 9
== PASS == X = 10 vs 10
== PASS == XI = 11 vs 11
== PASS == XII = 12 vs 12
== PASS == XIII = 13 vs 13
== PASS == XIV = 14 vs 14
== PASS == XV = 15 vs 15
== PASS == XVI = 16 vs 16
== PASS == XVII = 17 vs 17
== PASS == XVIII = 18 vs 18
== PASS == XIX = 19 vs 19
== PASS == XVIIII = 19 vs 19
== PASS == XX = 20 vs 20
== PASS == XXI = 21 vs 21
== PASS == XXX = 30 vs 30
== PASS == XL = 40 vs 40
== PASS == L = 50 vs 50
== PASS == LXXVIII = 78 vs 78
== PASS == XCVIII = 98 vs 98
== PASS == IC = 99 vs 99
== PASS == XCIX = 99 vs 99
== PASS == C = 100 vs 100
== PASS == D = 500 vs 500
== PASS == M = 1000 vs 1000
== PASS == MMMDCCCLXXXVIII = 3888 vs 3888
== PASS == MDCMMCCLXIIIIII = 3666 vs 3666
Note that the last 'number' is horribly bogus (1000 + 500 + 900 + 1000 + 100 + 100 + 50 + 10 + 1 + 1 + 1 + 1 + 1 + 1).
Related
I just started learning C (I'm an absolute beginner) and I'm trying to make a program that translates Roman numbers to Arabic and vice versa.
If I were to type "IX" my program should give me a "9" as an output but instead I get a "1". I tried to find the issue on my own using the debugger and I can see my program entering the first If-Statement
if (userString[localIndex] == 'I')
but then it skips the inner If-Statement
else if (userString[++localIndex] == 'X') {
ARABIC_NUM += 9;
localIndex++;
}
I'm not sure why this is happening. If I type "IV" my program outputs a "4" which is the correct answer but if I type "IVIV" my programs once again outputs a lonely "4" and ignores the rest of my input.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#define NOT_A_NUMBER 0
#define IS_ROMAN 1
#define IS_ARABIC 2
int ARABIC_NUM = 0;
int findStringLength(char* userString) {
int stringLength = 0;
size_t index = 0;
while (userString[index] != '\0')
{
if (userString[index] != '\0') {
stringLength++;
index++;
}
}
return stringLength;
}
void resetString(char* userString)
{
size_t stringLength = findStringLength(userString);
for (size_t index = 0; index < stringLength; index++)
{
userString[index] = '\0';
}
}
void printString(char* userString)
{
size_t stringLength = findStringLength(userString);
for (size_t index = 0; index < stringLength; index++)
{
if (userString[index] != '\0')
printf("~%zu:%c~ ", index, userString[index]);
else
printf("Null character");
}
}
bool ifEnd(char* numberInput, size_t counter) {
bool userEnd = false;
for (size_t index = 0; index < counter; index++)
{
if ((numberInput[index - 2] == 'E' && numberInput[index - 1] == 'N' && numberInput[index] == 'D')) {
userEnd = true;
}
}
return userEnd;
}
int isNumTrue(char userChar) {
int isRoman = NOT_A_NUMBER;
int isArabic = NOT_A_NUMBER;
if (userChar == 'I' || userChar == 'V' || userChar == 'X' ||
userChar == 'L' || userChar == 'C' || userChar == 'D' || userChar == 'M') {
isRoman = IS_ROMAN;
return isRoman;
}
else if (userChar == '0' || userChar == '1' || userChar == '2' || userChar == '3' || userChar == '4' || userChar == '5' || userChar == '6' || userChar == '7' || userChar == '8' || userChar == '9') {
isArabic = IS_ARABIC;
return isArabic;
}
else {
return NOT_A_NUMBER;
}
}
void convertToArabic(char* userString, size_t counter) {
for (size_t localIndex = 0; userString[localIndex] != '\0'; localIndex++) {
// printf("[ %c%s]", userString[localIndex], "-o ");
if (userString[localIndex] == 'I') {
if (userString[++localIndex] == 'V') {
printf("Made it in");
ARABIC_NUM += 4;
localIndex++;
}
else if (userString[++localIndex] == 'X') {
ARABIC_NUM += 9;
localIndex++;
}
else {
ARABIC_NUM += 1;
}
}
else if (userString[localIndex] == 'V') {
ARABIC_NUM += 5;
}
else if (userString[localIndex] == 'X') {
if (userString[localIndex++] == 'L') {
ARABIC_NUM += 40;
localIndex++;
}
else if (userString[localIndex++] == 'C') {
ARABIC_NUM += 90;
localIndex++;
}
else {
ARABIC_NUM += 10;
}
}
else if (userString[localIndex] == 'L') {
ARABIC_NUM += 50;
}
else if (userString[localIndex] == 'C') {
if (userString[localIndex++] == 'D') {
ARABIC_NUM += 400;
localIndex++;
}
else if (userString[localIndex++] == 'M') {
ARABIC_NUM += 900;
localIndex++;
}
else {
ARABIC_NUM += 100;
}
}
else if (userString[localIndex] == 'D') {
ARABIC_NUM += 500;
}
else if (userString[localIndex] == 'M') {
ARABIC_NUM += 1000;
}
else {
printf("Switch default. You shouldn't be seeing this");
}
/* else
{
printf("[ %c%s]", userString[localIndex],"-x ");
}*/
}
printf("%s%d%s", "\n Number was :", ARABIC_NUM, "\n");
}
bool convertToRoman(char* userString, char* romanStringHolder, size_t counter) {
bool isValid = true;
int arabicNum = atoi(userString);
char repetitionLimit = '\0';
for (size_t index = 0; arabicNum != 0; index++) {
/* if ((isNumTrue(userString[index]) == IS_ARABIC || userString[index] == '\n') && index < counter)
{
printf("[ %c%s]", userString[index], "-o ");
}*/
if (arabicNum >= 4000) {
do {
if (romanStringHolder[index - 2] == romanStringHolder[index - 1] == romanStringHolder[index]) {
repetitionLimit = romanStringHolder[index - 2];
}
if (arabicNum / 1000000 >= 1)//&& repetitionLimit != 'M')
{
romanStringHolder[index] = 'M';
arabicNum -= 1000000;
}
else if (arabicNum / 900000 >= 1)// && repetitionLimit != 'M')
{
romanStringHolder[index] = 'C';
romanStringHolder[++index] = 'M';
arabicNum -= 900000;
}
else if (arabicNum / 500000 >= 1)// && repetitionLimit != 'D')
{
romanStringHolder[index] = 'D';
arabicNum -= 500000;
}
else if (arabicNum / 400000 >= 1)//&& repetitionLimit != 'D')
{
romanStringHolder[index] = 'C';
romanStringHolder[++index] = 'D';
arabicNum -= 400000;
}
else if (arabicNum / 100000 >= 1)// && repetitionLimit != 'C')
{
romanStringHolder[index] = 'C';
arabicNum -= 100000;
}
else if (arabicNum / 90000 >= 1)//&& repetitionLimit != 'C')
{
romanStringHolder[index] = 'X';
romanStringHolder[++index] = 'C';
arabicNum -= 90000;
}
else if (arabicNum / 50000 >= 1)// && repetitionLimit != 'L')
{
romanStringHolder[index] = 'L';
arabicNum -= 50000;
}
else if (arabicNum / 40000 >= 1)// && repetitionLimit != 'L')
{
romanStringHolder[index] = 'X';
romanStringHolder[++index] = 'L';
arabicNum -= 40000;
}
else if (arabicNum / 10000 >= 1)//&& repetitionLimit != 'X')
{
romanStringHolder[index] = 'X';
arabicNum -= 10000;
}
else if (arabicNum / 9000 >= 1)// && repetitionLimit != 'X')
{
romanStringHolder[index] = 'I';
romanStringHolder[++index] = 'X';
arabicNum -= 9000;
}
else if (arabicNum / 5000 >= 1)//&& repetitionLimit != 'V')
{
romanStringHolder[index] = 'V';
arabicNum -= 5000;
}
else if (arabicNum / 4000 >= 1)//&& repetitionLimit != 'I')
{
romanStringHolder[index] = 'I';
romanStringHolder[++index] = 'V';
arabicNum -= 4000;
}
else if (arabicNum / 1000 >= 1)// && repetitionLimit != 'I')
{
romanStringHolder[index] = 'I';
arabicNum -= 1000;
}
index++;
} while (arabicNum >= 4000);
romanStringHolder[index] = '_';
index++;
}
if (arabicNum <= 3999) {
if (arabicNum / 1000 >= 1)
{
romanStringHolder[index] = 'M';
arabicNum -= 1000;
}
if (arabicNum / 900 >= 1)
{
romanStringHolder[index] = 'C';
romanStringHolder[++index] = 'M';
arabicNum -= 900;
}
else if (arabicNum / 500 >= 1)
{
romanStringHolder[index] = 'D';
arabicNum -= 500;
}
else if (arabicNum / 400 >= 1)
{
romanStringHolder[index] = 'C';
romanStringHolder[++index] = 'D';
arabicNum -= 400;
}
else if (arabicNum / 100 >= 1)
{
romanStringHolder[index] = 'C';
arabicNum -= 100;
}
else if (arabicNum / 90 >= 1)
{
romanStringHolder[index] = 'X';
romanStringHolder[++index] = 'C';
arabicNum -= 90;
}
else if (arabicNum / 50 >= 1)
{
romanStringHolder[index] = 'L';
arabicNum -= 50;
}
else if (arabicNum / 40 >= 1)
{
romanStringHolder[index] = 'X';
romanStringHolder[++index] = 'L';
arabicNum -= 40;
}
else if (arabicNum / 10 >= 1)
{
romanStringHolder[index] = 'X';
arabicNum -= 10;
}
else if (arabicNum / 9 >= 1)
{
romanStringHolder[index] = 'I';
romanStringHolder[++index] = 'X';
arabicNum -= 9;
}
else if (arabicNum / 5 >= 1)
{
romanStringHolder[index] = 'V';
arabicNum -= 5;
}
else if (arabicNum / 4 >= 1)
{
romanStringHolder[index] = 'I';
romanStringHolder[++index] = 'V';
arabicNum -= 4;
}
else if (arabicNum / 1 >= 1)
{
romanStringHolder[index] = 'I';
arabicNum -= 1;
}
}
}
if (romanStringHolder > 3999999)
printf("\n");
return isValid;
}
int findNumSystem(char* userString, char* toRomanString) {
//printf(" -%zu and %d-", counter, findStringLength(userString));
size_t counter = findStringLength(userString);
int romanNumAmount = 0;
int arabicNumAmount = 0;
int notNumAmount = 0;
for (size_t localIndex = 0; localIndex < counter; localIndex++) {
if (isNumTrue(userString[localIndex]) == IS_ROMAN || ((isNumTrue(userString[localIndex - 1]) == IS_ROMAN) && (userString[localIndex] == '\n')))
{
printf("[ %c%s]", userString[localIndex], "-R ");
romanNumAmount++;
if (romanNumAmount == (findStringLength(userString) - 1)) {
printf("\nAll Numbers are Roman");
convertToArabic(userString, counter);
break;
}
}
else if (isNumTrue(userString[localIndex]) == IS_ARABIC || ((isNumTrue(userString[localIndex - 1]) == IS_ARABIC) && (userString[localIndex] == '\n')))
{
printf("[ %c%s]", userString[localIndex], "-A ");
arabicNumAmount++;
if (arabicNumAmount == (findStringLength(userString) - 1))
{
printf("\nAll numbers are Arabic");
convertToRoman(userString, toRomanString, counter);
printString(toRomanString);
break;
}
}
else if (isNumTrue(userString[localIndex]) == NOT_A_NUMBER)
{
printf("[ %c%s]", userString[localIndex], "-X ");
notNumAmount++;
if (notNumAmount == (findStringLength(userString))) {
printf("\nNone of the characters is a number of either system");
}
}
}
}
#define LENGTH 1000u
int main() {
typedef char user_Input_Stream;
char lol = '\0';
user_Input_Stream arabToRomanString[LENGTH] = { '\0' };
user_Input_Stream numberInput[LENGTH] = { '\0' };
size_t counter = 0;
bool userEnd = false;
while ((lol != EOF) && (userEnd == false))
{
counter = 0;
printString(&numberInput);
resetString(&numberInput);
resetString(&arabToRomanString);
counter = 0;
printString(&numberInput);
ARABIC_NUM = 0;
printf("\n\n||Beta version, remember to not mix number systems yet||\n");
//Repeats until variable lol countains EOF or until boolean holds a true value
while ((lol != EOF) && (lol != '\n') && (userEnd == false))
{
//gets characters, assigns string with them. Gets rid of newline and stores string in array in uppercase
lol = getchar();
numberInput[counter] = toupper(lol);
userEnd = ifEnd(numberInput, counter);
counter++;
}
//TESTING Travels through String and outputs cells contents. Also, sets boolean to True if user writes END
for (size_t i = 0; i < counter; i++) {
if (numberInput[i] == '\n')
{
lol = '\\';
numberInput[i] = toupper(lol);
}
// printf("| [%zu] = %c |", i, numberInput[i]);
}
findNumSystem(numberInput, arabToRomanString);
printf("\n");
}
printf("\n");
return 0;
}
Does anyone have an idea of what the issue could be? (ARABIC_NUM is a global variable, the name is to make it easier for me to find for now.)
Just in case this might help somebody else, here's the solution I came up with using some of the pointers people in the comment section gave me. It was fairly simple:
I was under the impression that expressions within if-statements don't affect any variables they reference, but in reality they do.
For example: if(userString[localIndex] == 'I' && userString[localIndex++] == 'X')
In the line above, I was expecting the program to check both the current index and the next upcoming index, which it did but the expression userString[localIndex++] within the if-statement also permanently incremented my localIndex variable when I wasn't expecting that change to exist outside of the if-statement's parenthesis. So, my program would check the wrong indexes after the first comparison was made and thus why it gave me the wrong output.
To solve this, I created the variable nextIndex and used it to store the value localIndex +1 meaning it will always represent the index after localIndex. So, It now works as intended.
Below is what my program looks like now. (I moved around the if and if-else statements for better readability but the only changed that solved my predicament was the addition of nextIndex)
void convertToArabic(char* userString, size_t counter) {
size_t nextIndex = 0;
for (size_t localIndex = 0; localIndex < findStringLength(userString); localIndex++) {
// printf("[ %c%s]", userString[localIndex], "-o ");
nextIndex = localIndex+1;
if (userString[localIndex] == 'M') {
ARABIC_NUM += 1000;
}
else if (userString[localIndex] == 'C' && userString[nextIndex] == 'M') {
ARABIC_NUM += 900;
localIndex++;
}
else if (userString[localIndex] == 'D') {
ARABIC_NUM += 500;
}
else if (userString[localIndex] == 'C' && userString[nextIndex] == 'D') {
ARABIC_NUM += 400;
localIndex++;
}
else if(userString[localIndex] == 'C'){
ARABIC_NUM += 100;
}
else if (userString[localIndex] == 'X' && userString[nextIndex] == 'C') {
ARABIC_NUM += 90;
localIndex++;
}
else if (userString[localIndex] == 'L') {
ARABIC_NUM += 50;
}
else if (userString[localIndex] == 'X' && userString[nextIndex] == 'L'){
ARABIC_NUM += 40;
localIndex++;
}
else if (userString[localIndex] == 'X') {
ARABIC_NUM += 10;
}
else if ((userString[localIndex] == 'I') && (userString[nextIndex] == 'X')) {
//localIndex--;
ARABIC_NUM += 9;
localIndex++;
}
else if (userString[localIndex] == 'V') {
ARABIC_NUM += 5;
}
else if ((userString[localIndex] == 'I') && (userString[nextIndex] == 'V')) {
//localIndex--;
printf("Made it in");
ARABIC_NUM += 4;
localIndex++;
}
else if (userString[localIndex] == 'I') {
ARABIC_NUM += 1;
}
/* else
{
printf("[ %c%s]", userString[localIndex],"-x ");
}*/
}
printf("%s%d%s", "\n Number was :", ARABIC_NUM, "\n");
}
I have struct input parameter and array of it called input_arr. I want to fill the array with the text as it gives the wrong value for the id and it work correctly with the name and nothing appear in visible.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct input_parameter {
int id;
char name[30];
int position;
char visible[5];
char required[5];
char parameter_type;
char client_id[5];
int min_length;
int max_length;
char confirm_required[5];
};
struct input_parameter input_arr[10];
char text[2*1024]="{\"success\": true,\"language\":
\"en\",\"action\":
\"GetServiceInputParameterList\",\"version\": 1,\"data\": {
\"input_parameter_list\": [{\"id\": 1489,\"service_id\":
12102,\"name\": \"Customer Number\",\"position\":
1,\"visible\":
true,\"required\": true,\"parameter_type\":
\"N\",\"client_id\":
true,\"min_length\": 11, \"max_length\":
11,\"confirm_required\":
false } ] }}";
Fill an array of structs with the text:
int main() {
int i = 0;
int Wstart = 0;
int Wend = 0;
char name[19] = {0x20};
char name1[19] = {0x20};
int menunum = 0;
int len = strlen(text);
while (1) // while ALL
{
if (i >= len) {
break;
}
if (text[i] == 'i' && text[i + 1] == 'd') {
while (1) { // while id
if (text[i] == ':') {
Wstart = i + 1;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i;
strncpy(name, text + Wstart, Wend - Wstart);
input_arr[menunum].id = atoi(name);
memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while id
} else if (text[i] == 'n' && text[i + 1] == 'a' && text[i + 2] == 'm' &&
text[i + 3] == 'e') {
while (1) { // while name
if (text[i] == ':') {
Wstart = i + 3;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i - 1;
strncpy(name, text + Wstart, Wend - Wstart);
// name[Wend-Wstart] = '\0';
// memset(name1, 0, sizeof(name1));
if ((name[1] >= 'a' && name[1] <= 'z') ||
(name[1] >= 'A' && name[1] <= 'Z')) {
// printf("%c is an alphabet.",c);
strcpy(name1, name);
} else {
int vc = 0;
int ia = strlen(name) - 1;
for (ia = strlen(name) - 1; ia >= 0; ia--) {
name1[vc] = name[ia];
vc++;
}
}
strcpy(input_arr[menunum].name, name1);
menunum++;
memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while name
} else if (text[i] == 'v' && text[i + 1] == 'i' && text[i + 2] == 's' &&
text[i + 3] == 'i' && text[i + 4] == 'b' &&
text[i + 5] == 'l' && text[i + 6] == 'e') {
while (1) { // while visible
if (text[i] == ':') {
Wstart = i + 3;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i - 1;
strncpy(name, text + Wstart, Wend - Wstart);
// name[Wend-Wstart] = '\0';
memset(name1, 0, sizeof(name1));
if ((name[1] >= 'a' && name[1] <= 'z') ||
(name[1] >= 'A' && name[1] <= 'Z')) {
// printf("%c is an alphabet.",c);
strcpy(name1, name);
} else {
int vc = 0;
int ia = strlen(name) - 1;
for (ia = strlen(name) - 1; ia >= 0; ia--) {
name1[vc] = name[ia];
vc++;
}
}
strcpy(input_arr[menunum].visible, name1);
menunum++;
// memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while visible
} else {
i++;
}
}
printf("id:%d \n name: %s \n visible: %s
\n",&input_arr[0].id,&input_arr[0].name,&input_arr[0].visible);
return 0;
}
Well you are printing address of id instead of its value using %d format specifier.
printf("id:%d\nname: %s\n visible: %d\n",&input_arr[0].id,&input_arr[0].name,&input_arr[0].visible);
should be
printf("id:%d \n name: %s \n visible: %d\n",input_arr[0].id,input_arr[0].name,input_arr[0].visible);
Following my previous question about making a snake program more fluid, I went and tried ANSI escape sequences and console functions to put back the text cursor on the top left corner.
I want to get the cursor on the top left corner of the screen, but while it does so I get black stripes across the screen every other line.
I am working in a windows environment making this program for the windows console.
Here is the painting function :
void paint(int tab[28][120], int ligneMax, int colonneMax, HANDLE hconsole)
{
//system("cls");
//printf("\033[1;1H");
COORD destCoord;
destCoord.X = 0;
destCoord.Y = 0;
SetConsoleCursorPosition(hconsole, destCoord);
for (int i = 0; i < ligneMax; i++)
{
for (int j = 0; j < colonneMax; j++)
{
printf("%c", tab[i][j]);
}
printf("\n");
}
}
I tried putting the escape code and console function in the main right before calling the paint function but I got the same results.
here is the whole program if someone wants to test :
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>
void paint(int tab[28][120], int ligneMax, int colonneMax, HANDLE hconsole)
{
//system("cls");
//printf("\033[1;1H");
COORD destCoord;
destCoord.X = 0;
destCoord.Y = 0;
SetConsoleCursorPosition(hconsole, destCoord);
for (int i = 0; i < ligneMax; i++)
{
for (int j = 0; j < colonneMax; j++)
{
printf("%c", tab[i][j]);
}
printf("\n");
}
}
void create(int tab[28][120], int Nbligne, int Nbcolonne,
int randligne, int randcols)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
tab[i][j] = ' ';
if (i == 0 || i == Nbligne - 1)
tab[i][j] = 205;
if (j == 0 || j == Nbcolonne - 1)
tab[i][j] = 186;
if (i == 0 && j == 0)
tab[i][j] = 201;
if (i == 0 && j == Nbcolonne - 1)
tab[i][j] = 187;
if (i == Nbligne - 1 && j == 0)
tab[i][j] = 200;
if (i == Nbligne - 1 && j == Nbcolonne - 1)
tab[i][j] = 188;
if (i == 14 && j == 60)
tab[i][j] = 219;
if (i == 14 && j == 59)
tab[i][j] = 79;
if (i == 14 && j == 58)
tab[i][j] = 35;
if (i == randligne && j == randcols)
tab[i][j] = 176;
}
}
}
void destroyTail(int tab[28][120], int Nbligne, int Nbcolonne)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if (tab[i][j] == 35)
{
tab[i][j] = ' ';
if (tab[i][j + 1] == 79)
tab[i][j + 1] = 35;
else if (tab[i][j - 1] == 79)
tab[i][j - 1] = 35;
else if (tab[i + 1][j] == 79)
tab[i + 1][j] = 35;
else if (tab[i - 1][j] == 79)
tab[i - 1][j] = 35;
goto stop;
}
}
}
stop: NULL;
}
void translate(int tab[28][120], char direction, int Nbligne, int Nbcolonne)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if (tab[i][j] == 219)
{
if (direction == 'R')
{
tab[i][j] = 79;
tab[i][j + 1] = 219;
}
if (direction == 'D')
{
tab[i][j] = 79;
tab[i + 1][j] = 219;
}
if (direction == 'L')
{
tab[i][j] = 79;
tab[i][j - 1] = 219;
}
if (direction == 'U')
{
tab[i][j] = 79;
tab[i - 1][j] = 219;
}
goto stop;
}
}
}
stop: NULL;
}
int checkExpand(int tab[28][120], int Nbligne, int Nbcolonne, char direction)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if ((direction == 'R' && tab[i][j] == 219 && tab[i][j + 1] == 176) ||
(direction == 'L' && tab[i][j] == 219 && tab[i][j - 1] == 176) ||
(direction == 'U' && tab[i][j] == 219 && tab[i - 1][j] == 176) ||
(direction == 'D' && tab[i][j] == 219 && tab[i + 1][j] == 176))
return 1;
}
}
return 0;
}
int checkDeath(int tab[28][120], int Nbligne, int Nbcolonne, char direction)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if ((direction == 'R' && tab[i][j] == 219 && (tab[i][j + 1] == 186 || tab[i][j + 1] == 79)) ||
(direction == 'L' && tab[i][j] == 219 && (tab[i][j - 1] == 186 || tab[i][j - 1] == 79)) ||
(direction == 'U' && tab[i][j] == 219 && (tab[i - 1][j] == 205 || tab[i - 1][j] == 79)) ||
(direction == 'D' && tab[i][j] == 219 && (tab[i + 1][j] == 205 || tab[i + 1][j] == 79)))
return 1;
}
}
return 0;
}
int main()
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 241);
int tab[28][120];
int randligne = rand() % 26 + 1;
int randcols = rand() % 118 + 1;
create(tab, 28, 120, randligne, randcols);
paint(tab, 28, 120, hConsole);
char i = '1';
char direction = 'R';
int eaten = 0;
int expand = 0;
int death = 0;
while(i != 'k')
{
if (kbhit())
i = getch();
switch(i) {
case 'z':
if (direction != 'D')
direction = 'U';
break;
case 's':
if (direction != 'U')
direction = 'D';
break;
case 'd':
if (direction != 'L')
direction = 'R';
break;
case 'q':
if (direction != 'R')
direction = 'L';
break;
}
randligne = rand() % 26 + 1;
randcols = rand() % 118 + 1;
death = checkDeath(tab, 28, 120, direction);
if (death == 1)
break;
translate(tab, direction, 28, 120);
expand = checkExpand(tab, 28, 120, direction);
if (expand == 0)
destroyTail(tab, 28, 120);
else
{
while (tab[randligne][randcols] != ' ')
{
randligne = rand() % 26 + 1;
randcols = rand() % 118 + 1;
}
tab[randligne][randcols] = 176;
eaten++;
}
printf("Number of biscuits eaten : %d ; direction : %c ; expand : %d", eaten, direction, expand);
paint(tab, 28, 120, hConsole);
Sleep(100);
}
while(i != 'k')
{
if (kbhit())
i = getch();
}
}
Too much code to take in quickly. If you have Windows console ouput for the snake, can't you simply printf the next line and leave it at that?
If you want to hide the cursor (instead of trying to park it out of sight) you can make it invisible by calling SetConsoleCursorInfo and the struct passed is shown here.
I need to convert amount in words. For example, the amount I will get it from service is 9876, I need to display in a table "Nine Thousand Eight Hundred and Seventy Six" in a table.
I need to do this using angularjs. Please help me how can I do this.
JSFIDDLE
function convertNumberToWords(amount) {
var words = new Array();
words[0] = '';
words[1] = 'One';
words[2] = 'Two';
words[3] = 'Three';
words[4] = 'Four';
words[5] = 'Five';
words[6] = 'Six';
words[7] = 'Seven';
words[8] = 'Eight';
words[9] = 'Nine';
words[10] = 'Ten';
words[11] = 'Eleven';
words[12] = 'Twelve';
words[13] = 'Thirteen';
words[14] = 'Fourteen';
words[15] = 'Fifteen';
words[16] = 'Sixteen';
words[17] = 'Seventeen';
words[18] = 'Eighteen';
words[19] = 'Nineteen';
words[20] = 'Twenty';
words[30] = 'Thirty';
words[40] = 'Forty';
words[50] = 'Fifty';
words[60] = 'Sixty';
words[70] = 'Seventy';
words[80] = 'Eighty';
words[90] = 'Ninety';
amount = amount.toString();
var atemp = amount.split(".");
var number = atemp[0].split(",").join("");
var n_length = number.length;
var words_string = "";
if (n_length <= 9) {
var n_array = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0);
var received_n_array = new Array();
for (var i = 0; i < n_length; i++) {
received_n_array[i] = number.substr(i, 1);
}
for (var i = 9 - n_length, j = 0; i < 9; i++, j++) {
n_array[i] = received_n_array[j];
}
for (var i = 0, j = 1; i < 9; i++, j++) {
if (i == 0 || i == 2 || i == 4 || i == 7) {
if (n_array[i] == 1) {
n_array[j] = 10 + parseInt(n_array[j]);
n_array[i] = 0;
}
}
}
value = "";
for (var i = 0; i < 9; i++) {
if (i == 0 || i == 2 || i == 4 || i == 7) {
value = n_array[i] * 10;
} else {
value = n_array[i];
}
if (value != 0) {
words_string += words[value] + " ";
}
if ((i == 1 && value != 0) || (i == 0 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Crores ";
}
if ((i == 3 && value != 0) || (i == 2 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Lakhs ";
}
if ((i == 5 && value != 0) || (i == 4 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Thousand ";
}
if (i == 6 && value != 0 && (n_array[i + 1] != 0 && n_array[i + 2] != 0)) {
words_string += "Hundred and ";
} else if (i == 6 && value != 0) {
words_string += "Hundred ";
}
}
words_string = words_string.split(" ").join(" ");
}
return words_string;
}
<input type="text" name="number" placeholder="Number OR Amount" onkeyup="word.innerHTML=convertNumberToWords(this.value)" />
<div id="word"></div>
I refered this javascript fiddle. But I want to it in a angularjs.
I used this for Angular 8.
Input : 123456789.09 Output : twelve crore thirty four lakh fifty six thousand seven eighty nine point zero nine
n: string;
a = ['zero ', 'one ', 'two ', 'three ', 'four ', 'five ', 'six ', 'seven ', 'eight ', 'nine ', 'ten ', 'eleven ', 'twelve ', 'thirteen ', 'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen '];
b = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
ngOnInit(): void {
console.log(this.inWords(123456789.09));
}
inWords (num): string {
num = Math.floor(num * 100);
if ((num = num.toString()).length > 11) { return 'overflow'; }
let n;
n = ('00000000' + num).substr(-11).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})(\d{1})(\d{1})$/);
if (!n) { return; } let str = '';
// tslint:disable-next-line:triple-equals
str += (n[1] != 0) ? (this.a[Number(n[1])] || this.b[n[1][0]] + ' ' + this.a[n[1][1]]) + 'crore ' : '';
// tslint:disable-next-line:triple-equals
str += (n[2] != 0) ? (this.a[Number(n[2])] || this.b[n[2][0]] + ' ' + this.a[n[2][1]]) + 'lakh ' : '';
// tslint:disable-next-line:triple-equals
str += (n[3] != 0) ? (this.a[Number(n[3])] || this.b[n[3][0]] + ' ' + this.a[n[3][1]]) + 'thousand ' : '';
// tslint:disable-next-line:triple-equals
str += (n[4] != 0) ? (this.a[Number(n[4])] || this.b[n[4][0]] + ' ' + this.a[n[4][1]]) : 'hundred';
// tslint:disable-next-line:triple-equals
str += (n[5]) ? (this.a[Number(n[5])] || this.b[n[5][0]] + ' ' + this.a[n[5][1]]) : '';
// tslint:disable-next-line:triple-equals
str += (n[6]) ? ((str != '') ? 'point ' : '') + (this.a[Number(n[6])] || this.b[n[6][0]] + ' ' + this.a[n[6][1]]) : '';
// tslint:disable-next-line:triple-equals
str += (n[7] != 0) ? (this.a[Number(n[7])] || this.b[n[7][0]] + ' ' + this.a[n[7][1]]) : '';
return str;
}
Define a filter to convert number to word such as following code:
angular.module('myModuleName')
.filter('convertToWord', function() {
return function(amount) {
var words = new Array();
words[0] = '';
words[1] = 'One';
words[2] = 'Two';
words[3] = 'Three';
words[4] = 'Four';
words[5] = 'Five';
words[6] = 'Six';
words[7] = 'Seven';
words[8] = 'Eight';
words[9] = 'Nine';
words[10] = 'Ten';
words[11] = 'Eleven';
words[12] = 'Twelve';
words[13] = 'Thirteen';
words[14] = 'Fourteen';
words[15] = 'Fifteen';
words[16] = 'Sixteen';
words[17] = 'Seventeen';
words[18] = 'Eighteen';
words[19] = 'Nineteen';
words[20] = 'Twenty';
words[30] = 'Thirty';
words[40] = 'Forty';
words[50] = 'Fifty';
words[60] = 'Sixty';
words[70] = 'Seventy';
words[80] = 'Eighty';
words[90] = 'Ninety';
amount = amount.toString();
var atemp = amount.split(".");
var number = atemp[0].split(",").join("");
var n_length = number.length;
var words_string = "";
if (n_length <= 9) {
var n_array = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0);
var received_n_array = new Array();
for (var i = 0; i < n_length; i++) {
received_n_array[i] = number.substr(i, 1);
}
for (var i = 9 - n_length, j = 0; i < 9; i++, j++) {
n_array[i] = received_n_array[j];
}
for (var i = 0, j = 1; i < 9; i++, j++) {
if (i == 0 || i == 2 || i == 4 || i == 7) {
if (n_array[i] == 1) {
n_array[j] = 10 + parseInt(n_array[j]);
n_array[i] = 0;
}
}
}
value = "";
for (var i = 0; i < 9; i++) {
if (i == 0 || i == 2 || i == 4 || i == 7) {
value = n_array[i] * 10;
} else {
value = n_array[i];
}
if (value != 0) {
words_string += words[value] + " ";
}
if ((i == 1 && value != 0) || (i == 0 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Crores ";
}
if ((i == 3 && value != 0) || (i == 2 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Lakhs ";
}
if ((i == 5 && value != 0) || (i == 4 && value != 0 && n_array[i + 1] == 0)) {
words_string += "Thousand ";
}
if (i == 6 && value != 0 && (n_array[i + 1] != 0 && n_array[i + 2] != 0)) {
words_string += "Hundred and ";
} else if (i == 6 && value != 0) {
words_string += "Hundred ";
}
}
words_string = words_string.split(" ").join(" ");
}
return words_string;
};
});
Then in your templates (views) use this filter as follow:
{{amount | converToWord}}
For example to show inserted value in an input field:
<input type="text" name="number" placeholder="Number OR Amount" ng-model="myValue" />
<div id="word">{{myValue | convertToWord}}</div>
I am making a maze using Depth-First search algorithm as a school project. The maze is working pretty much as I want but I have a little problem. I have to use # as a wall and . as a path when printing the maze but I used 0 as a wall and 1 as a path at first thinking that it is gonna be easy to change it later but I was wrong. How can I change 0 and 1 into # and .?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void nahodne_suradnice(int *r, int *s, int n)
{
srand(time(NULL));
*r = ((rand() % n) - 1) + 2;
if (*r == 1 || *r == n)
{
*s = (rand() % n) + 2;
}
else
{
if (rand() % 2 == 1)
*s = 1;
else
*s = n;
}
}
int main()
{
int i, j, n, r, s,smer,posledny_smer[1500];
int maze[500][500];
scanf_s("%d", &n);
if (n < 10 || n > 100)
{
return 0;
}
//vynulovanie pola/bludiska
for (i = 1; i < n + 1; i++)
{
for (j = 1; j < n + 1; j++)
{
maze[i][j] = 0;
}
}
//nahodny vyber zaciatku bludiska
nahodne_suradnice(&r, &s, n);
//generovanie bludiska
j = 0;
maze[r][s] = 2;
for (i = 0 ;; i++)
{
//backtracking
if ((maze[r - 1][s] == 1 || maze[r - 2][s] == 1 || r - 2 <=1 || s==n || s==1) && (maze[r][s + 1] == 1 || maze[r][s + 2] == 1 || s + 2 >= n || r == n || r==1) && (maze[r + 1][s] == 1 || maze[r + 2][s] == 1 || r + 2 >= n || s == n || s==1) && (maze[r][s - 1] == 1 || maze[r][s - 2] == 1 || s - 2 <=1 || r == n || r==1))
{
if (posledny_smer[j-1] == 1)
if (maze[r + 1][s] == 1 && maze[r + 2][s] == 1)
{
r += 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 2)
if (maze[r][s - 1] == 1 && maze[r][s - 2] == 1)
{
s -= 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 3)
if (maze[r - 1][s] == 1 && maze[r - 2][s] == 1)
{
r -= 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 4)
if (maze[r][s + 1] == 1 && maze[r][s + 2] == 1)
{
s += 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (j == 0)
{
if (r == n)
{
nahodne_suradnice(&r, &s,n);
maze[1][s] = 3;
maze[2][s] = 3;
}
if (r == 1)
{
nahodne_suradnice(&r, &s, n);
maze[n][s] = 3;
maze[n - 1][s] = 3;
}
if (s == n-2)
{
nahodne_suradnice(&r, &s, n);
maze[r][1] = 3;
maze[r][2] = 3;
}
if (s == 3)
{
nahodne_suradnice(&r, &s, n);
maze[r][n] = 3;
maze[r][n-1] = 3;
}
break;
}
}
//buranie stien
smer = (rand() % 4) + 1;
if (smer == 1)
{
if (r - 2 >1 && s<n && s>1)
{
if (maze[r - 1][s] == 1 || maze[r - 2][s] == 1)
continue;
maze[r - 1][s] = 1;
maze[r - 2][s] = 1;
r -= 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 2)
{
if (s + 2 < n && r < n && r>1)
{
if (maze[r][s+1] == 1 || maze[r][s+2] == 1)
continue;
maze[r][s + 1] = 1;
maze[r][s + 2] = 1;
s += 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 3)
{
if (r + 2 < n && s < n && s>1)
{
if (maze[r + 1][s] == 1 || maze[r + 2][s] == 1)
continue;
maze[r + 1][s] = 1;
maze[r + 2][s] = 1;
r += 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 4)
{
if (s - 2 >1 && r < n && r>1)
{
if (maze[r][s-1] == 1 || maze[r][s-2] == 1)
continue;
maze[r][s - 1] = 1;
maze[r][s - 2] = 1;
s -= 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
}
//vypis bludiska
for (i = 1; i < n + 1; i++)
{
for (j = 1; j < n + 1; j++)
{
printf("%d", maze[i][j]);
}
printf("\n");
}
system("PAUSE");
return 0;
}
`
Thanks.
Change the definition of maze to:
char maze[500][500]
and change all references to use char instead of int. Then return '#' and '.' instead of 0 and 1.
You can change from 0 and 1 to # and . (or any other representation) when printing. For instance you can change:
printf("%d", maze[i][j]);
to
switch(maze[i][j]) {
case 0:
printf("#");
break;
case 1:
printf(".");
break;
default:
printf("X"); /* in case you have some value other than 0 or 1 in the maze */
}
If you do it like this, you can change which letters you want to display the maze as without changing other parts of your code.