You are trying to divide the functionality between functions in a very strange way. If the transform() function is to perform an intermediate conversion of characters into numbers, then there is no need to impose on it also a data entry function. With the input of string data, the scanf() function does an excellent job. Moreover, it also has the ability to allocate memory for the lines entered ( %a ). If you don’t want to do memory allocation at all (even with scanf() ), then for character processing, the getchar() function can be called from an external function, passing the result inside the transform() . Leave the transform() function only for its proper actions.
For some reason, instead of passing a pointer to the current position in the array being processed by the recursion parameter in decimal() , you pass the address of the beginning of the array, and the pointer (more precisely, the index) goes in your global variable. Yes, in fact, recursion is completely unnecessary in this case, but only consumes extra space on the stack.
Global variables are evil. Data coupling between the functions must be zero if there is no vital necessity. Implicit function input parameters are evil. All data transfer must be done through arguments. Otherwise, in the future (with a more serious code and a larger scale of the project), huge problems of the “hemorrhoid” class are inevitable.
Moreover, these problems are already present in your code right now, since The transform() function works on the assumption that j is -1 at the start, however, if someone calls transform() several times, especially after calling decimal() -> fractional() , then at the entrance to tranform() variable j will have garbage value.
At the same time, ANYWHERE is not controlled anywhere beyond the bounds of the Array_F array! This guarantees problems. Actually this is the previous one - probably the root of the problems you have. In addition, printed but non-valid characters (spaces, punctuation marks other than dots, etc.) are not processed in any way.
It’s not at all clear why the decimal() function is needed if it actually complements the transform() functionality. And it does not translate into decimal form at all, but simply transforms an array of individual digits of an arbitrary number system created by the transform() function into a regular float number. It is NOT decimal at all. Rather, the binary is in IEEE754 format. It would be logical to combine all these three functions into one.
In general, I would completely redo this code like this:
#include <stdio.h> #include <ctype.h> #include <math.h> double transform_char(double in, char c, int base, int fractional_position) { int i; if(isalnum(c)) { if(isdigit(c)) { i = c - '0'; } else if(isalpha(c)) { if(isupper(c)) { i = c - 'A' + 10; } else { i = c - 'a' + 10; } } if(i > base - 1) { return -NAN; } if(!fractional_position) { in *= base; in += i; } else { double frac = in - (int)in; in -= frac; frac += (double)i / pow(base, (double)fractional_position); in += frac; } } return in; }
This function processes the string character by character. For the integer part, the fractional_position parameter must be zero. After detecting a point symbol in the incoming stream, it is necessary to set the parameter to 1 and then increment after each next processed symbol:
#include <stdbool.h> #include <stdlib.h> ... int input_base; double res = 0.0; char c = 0; bool fraction = false; int pos = 0; ... // Инициализация input_base где-то тут while((c = getchar()) != '\n') { int i; printf("%c: %g -> ", c, res); if(isalnum(c)) { res = transform_char(res, c, input_base, pos); if(isnan(res)) { fprintf(stderr, "Invalid digit %c for base %d\n", c, input_base); break; } if(pos) pos++; } else if('.' == c) { fraction = true; pos = 1; } else { fprintf(stderr, "Invalid character %c\n", c); return 1; } printf("%g\n", res); }
At the same time I draw your attention to the fact that the inverse transformation is a more complicated task. Although your limit of 13 characters makes it much easier. Solutions are set forth, for example, here: https://stackoverflow.com/questions/7228438/convert-double-float-to-string
Please also note that my code (like yours) does not know how to handle negative numbers, but this is easy to fix.
0.1into the decimal system, the result is0.333...infinite (periodic). Just cut back on length (same 13 characters)? Or search for a period and use()notation? - AnT