The task: the source string ( char ) contains the numbers of the decimal number system. Find them, create a new string in which to replace the numbers of the decimal number system with their own denomination in hexadecimal number system. Nechisla must be left in its place.

Example: 444444asdf should be converted to 6C81Casdf .

You cannot use standard functions and libraries.

My code can only translate numbers, if the string contains letters, it does not work. Please assist.

My implementation:

 #include <stdio.h> void inputChar(char *str) { printf("input array char <100: "); scanf("%s", str); } void revers(char *A) { int j; for (j = 0; A[j] != '\0'; j++); j--; for (int i = 0; i <j; i++, j--) { char temp = A[i]; A[i] = A[j]; A[j] = temp; } } int charToDecInt(char *A) { int summ = 0; for (int i = 0; A[i] != '\0'; i++) { if ('0' <= A[i] && A[i] <= '9') { summ *= 10; summ += A[i] - '0'; } else { summ += A[i]-'A'+10; } } return summ; } void decIntTohexString(int a, char *A) { int j = 0; while (a != 0) { int r = a % 16; if (r >= 1 && r <= 9) { r += '0'; } else { r += 'A'- 10; } A[j++] = r+A[j]; a /= 16; } A[j] = '\0'; revers(A); } void display() { const int N = 100; char A[N] = ""; char B[N] = ""; inputChar(A); int a = charToDecInt(A); decIntTohexString(a, B); printf("hexChar = %s\n", B); } int main() { display(); return 0; } 
  • What problem have you encountered? What is the question? - ߊߚߤߘ
  • my code does this: the source line is (for example) 444444, the output line is 6C81C. Those. it perfectly translates numbers from dec to hex. But if the string contains letter characters, then problems begin. you need to be like this: (for example) 444444asdf -> 6C81Casdf - Sergey Zinovev
  • What he translates well is good. Well, what's the difficulty? As far as I understand, you didn’t just ask a question just like that, but to solve a problem. - ߊߚߤߘ
  • The problem is precisely this, strictly speaking. My code from dec to hex only translates if the source string consists of only digit characters. If it contains letters, the code does not work. The original string should not change, it should only change the numbers in the decimal number system by the same numbers in the hexadecimal number system. - Sergey Zinovev
  • I do not know, everything works for me: ideone.com/6GSmhI . That is, the extra letters duplicate the console itself, but not the program. - ߊߚߤߘ

2 answers 2

  1. The current implementation of the charToDecInt() function contains a logical error:

     int charToDecInt(char *A) { int summ = 0; for (int i = 0; A[i] != '\0'; i++) { if ('0' <= A[i] && A[i] <= '9') { summ *= 10; summ += A[i] - '0'; } else // <-- (1) { summ += A[i]-'A'+10; } } return summ; } 

    An alternative condition branch (line (1) ) catches not only letters in the range [a-hA-h] , but in general any non-digit characters. Therefore, the cycle, having met the first non-hexadecimal digit, will spoil the whole generated number.

    The solution to the problem is to stop the cycle when it encounters not only the end of the line ( \0 ), but also a non-numeric character. To do this, rewrite the loop header as follows:

     for ( int i = 0; A[i] != '\0' && ((A[i] >= '0' && A[i] <= '9') || (A[i] >= 'A' && A[i] <= 'H')); i++ ) 
  2. To display the end of the line in an intact form, you need to track its position. The most optimal tracking option is right during the parsing of the number. In this case, the end of parsing will coincide with the beginning of the intact line.

    In other words, we must return from charToDecInt() not only the parsed number, but also the position of the end of the parsing.

    Since this is C, which does not support returning tuples, the position will have to be returned through one of the parameters of the function:

     int charToDecInt(const char *A, const char **outPos) { int summ = 0; int i = 0; // <-- for ( A[i] != '\0' && ((A[i] >= '0' && A[i] <= '9') || (A[i] >= 'A' && A[i] <= 'H')); i++ ) { if ('0' <= A[i] && A[i] <= '9') { summ *= 10; summ += A[i] - '0'; } else summ += A[i]-'A'+10; } *outPos = A + i; // <-- return summ; } 

    Accordingly, it is necessary to alter the output of the parsed numbers.

    1. For convenience of output, we make decIntTohexString() return the number of characters written.

       int decIntTohexString(int a, char *A) { int j = 0; while (a != 0) { int r = a % 16; if (r >= 1 && r <= 9) { r += '0'; } else { r += 'A'- 10; } A[j++] = r+A[j]; a /= 16; } A[j] = '\0'; revers(A); return A + j; // <-- да, мы возвращаем указатель на нуль-символ (всё равно затрём) } 
    2. Let's start with display() . Since there can be several numbers inside the string, and all of them are separated by characters other than hexadecimal numbers, the search and parsing will have to be performed in a loop. In the initial implementation, the program took only the very first number.

       int charToDecInt(char *A, char** outPos) { // ... } int decIntTohexString(int a, char *A) { // ... } void display() { #define N 100 char A[N] = ""; char B[N] = ""; inputChar(A); const char *itA = A; char *itB = B; while(*itA && itB - B < N) { // Ищем начало очередного числа while(*itA != '\0' && !((*itA >= '0' && *itA <= '9') || (*itA >= 'A' && *itA <= 'H')) ++itA; int a = charToDecInt(itA, &itA); // Выводим разобранное число itB = decIntTohexString(a, itB); printf("%s", itB ); } 
  • If interested, then I solved this problem. Without the use of standard functions and libraries. And without the use of pointers. - Sergey Zinovev

To whom it is interesting, I solved my task (without using standard functions and libraries and without using pointers):

 #include <stdio.h> #include <locale.h> int strLen(char *S) { int n; for (n = 0; S[n] != '\0'; n++); return n; } void revers(char *A) { int j; for (j = 0; A[j] != '\0'; j++); j--; for (int i = 0; i <j; i++, j--) { char temp = A[i]; A[i] = A[j]; A[j] = temp; } } void digitDecToHexString(int digit, char *T) { int j = 0; while (digit != 0) { int r = digit % 16; if (r >= 1 && r <= 9) { r += '0'; } else { r += 'A' - 10; } T[j++] = r; digit /= 16; } T[j] = '\0'; revers(T); } void intDecToCharHex(char *A, char *B) { int n = strLen(A); char Hex[1000] = ""; int i = 0; int j = 0; int k = 0; int v = 0; int p = 0; for(i = 0; i<n; i++) { if ('0' <= A[i] && A[i] <= '9') { v = v * 10 + (A[i] - '0'); k = 1; } else { if (k == 1) { digitDecToHexString(v, Hex); B[j++] = '0'; B[j++] = 'x'; for (p = 0; p < strLen(Hex); p++) { B[j++] = Hex[p]; } } B[j++] = A[i]; k = 0; v = 0; } } if (k == 1) { digitDecToHexString(v, Hex); B[j++] = '0'; B[j++] = 'x'; for (p = 0; p < strLen(Hex); p++) { B[j++] = Hex[p]; } } } void inputCharArray(char *S) { printf("Введите строку на латинском алфавите размерностью мене 1000 символов: \n"); scanf("%[^\n]s", S); } void display() { char A[1000] = { '\0' }; inputCharArray(A); char B[1000] = ""; intDecToCharHex(A, B); printf("Входная строка: \n%s\n", A); printf("Строка после обработки: \n%s\n", B); } int main() { setlocale(LC_ALL, "Rus"); display(); return 0; }