Разделение на триады. В чем ошибка? - C (СИ)
Формулировка задачи:
Помогите, пожалуйста, разобраться!
При запуске программа запрашивает все необходимые данные и прекращает работу. В чем у меня ошибка?
Заранее спасибо)
Задание выглядело примено так:
Функция в текстовом режиме выводит число num в 10-системе счисления группами по 3 цифры (триадами), отделяя их друг от друга символом term и возвращая 0.
Вставлен вот этот:
Теперь на экран выводится результат в виде непонятных случайных символов.
Проблема, как я понимаю в том, что temp у меня задана как int, а массив bits чаровый.
Вопрос остается тем же: как это можно исправить?
#include <STDIO.H> #include <CONIO.H> #define MAXY 20 #define MAXX 64 long GetLongNum( char *query, long minnum, long maxnum ) { long n; printf( "\n%s = ", query ); fflush( stdin ); if ( scanf( "%D", &n ) != 1 ) n = (minnum + maxnum) / 2; else if ( n < minnum ) n = minnum; else if ( n > maxnum ) n = maxnum; return n; } int GetNum( char *query, /* *текст запроса целого числа* */ int minnum, int maxnum ) { int n; /* буфер введенного числа */ printf( "\n%s = ", query ); fflush( stdin ); if ( scanf( "%d", &n ) != 1 ) n = (minnum + maxnum) / 2; else if ( n < minnum ) n = minnum; else if ( n > maxnum ) n = maxnum; return n; } int YesNo( char *text ) { int c; printf( "\n%s [Y/N]?", text ); fflush( stdin ); c = getchar(); if ( (c == 'y') || (c == 'Y') ) return 1; else return 0; } void LongToBits ( long num, char *bits ) { int k; int n; long c; k = 1000000000; for ( n = 0; n < 31; n++ ) { c = num/k; num = num - c*k; k = k/10; if( c == 0) bits[n] = '0'; if( c == 1) bits[n] = '1'; if( c == 2) bits[n] = '2'; if( c == 3) bits[n] = '3'; if( c == 4) bits[n] = '4'; if( c == 5) bits[n] = '5'; if( c == 6) bits[n] = '6'; if( c == 7) bits[n] = '7'; if( c == 8) bits[n] = '8'; if( c == 9) bits[n] = '9'; } } int TPutDecLong ( int x, int y, long num, char term ) { char bits[32]; int i; int n; int n1; /* номер позиции в тройке */ int n2; /* *номер тройки в числе */ char three[4]; /* строка в 3 символа* */ char devider[1];/* символ-разделитель */ int ccolor; /*цвет текста по умолчанию */ for ( i=0; i< 2; i++) devider[i] = '0'; devider[0] = term; devider[1] = '\0'; clrscr(); if ( y < 0 || y > MAXY ) return -1; /* слишком длинный столбец* */ if ( x < 0 || x > MAXX - 40 ) return -2; /* слишком длинная строка */ LongToBits( num, bits ); clrscr(); for ( n = 0; n < y; n++ ) printf( "\n" ); for ( n = 0; n < x; n++ ) printf( " " ); for ( n2 = 0; n2 < 9; n2++ ) { for ( n1 = 0; n1 < 3; n1++ ) { n = 31 - 3 * n2 - n1; three[n1] = bits[n]; } three[4] = '\0'; cprintf ( three ); cprintf ( devider ); } printf ( "\n" ); ccolor = WHITE; textcolor ( ccolor ); return 0; } void main (void) { extern int TPutDecLong (int x, int y,long num, char term ); extern int YesNo( char *text ); extern long GetLongNum( char *query,long minnum, long maxnum ); extern int GetNum( char *query,int minnum, int maxnum ); long number; long maxnum = 2000000000; /* 2*10^9 */ long minnum = -2000000000; int x,y; char term; int dcolor; int tcolor; int error; int ccolor = WHITE; do { clrscr(); textcolor ( ccolor ); number = GetLongNum ( "\nВведите число", minnum, maxnum ); x = GetNum ( "\nВведите координату Х", 0, 64 ); y = GetNum ( "\nВведите координату Y", 0, 20 ); printf ( "\nВведите символ-разделитель триад" ); term = getch(); error = TPutDecLong ( x, y, number, term ); if ( error == -1 ) printf ( "\nНеверно задано Х" ); if ( error == -2 ) printf ( "\nНевернозадано Y" ); printf ( "\nВведенное число:", number ); printf ( "\nКоордината Х: %d", x ); printf ( "\nКоордината Y: %d", y ); printf ( "\nСимвол-разделитель: %c", term ); } while ( YesNo ( "Повторить?" ) ); clrscr(); }
Вместо вот этого куска :
k = 1000000000; for ( n = 0; n < 31; n++ ) { c = num/k; num = num - c*k; k = k/10; if( c == 0) bits[n] = '0'; if( c == 1) bits[n] = '1'; if( c == 2) bits[n] = '2'; if( c == 3) bits[n] = '3'; if( c == 4) bits[n] = '4'; if( c == 5) bits[n] = '5'; if( c == 6) bits[n] = '6'; if( c == 7) bits[n] = '7'; if( c == 8) bits[n] = '8'; if( c == 9) bits[n] = '9'; }
k = 10; c = num; do { for ( n = 0; n < 31; n++ ) { temp = c%k; c = c/k; bits[n] = temp; } } while (c != 0);
Решение задачи: «Разделение на триады. В чем ошибка?»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> void Reverse(char* begin, char* end) { char tmp; for (; begin < end; ++begin, --end) { tmp = *begin; *begin = *end; *end = tmp; } } const char* GetIntAsAnsi(unsigned digit, char delim) { static char ansi[32] = {'\0'}; char* pstr = ansi; while (digit) { *pstr++ = digit % 10 + '0'; digit /= 10; if (digit && ((pstr - ansi + 1) % 4 == 0)) { *pstr++ = delim; } } *pstr = '\0'; Reverse(ansi, pstr - 1); return ansi; } int main() { printf("%s\n", GetIntAsAnsi(1234567, ':')); printf("%s\n", GetIntAsAnsi(12345, '.')); printf("%s\n", GetIntAsAnsi(123456789, '^')); return 0; }
Объяснение кода листинга программы
- В функции
Reverse
происходит переполнение буфера при копировании символов в обратном порядке. Причина в том, что в цикле не контролируется выход за границы выделенной памяти. В результате, при копировании последнего символа, происходит запись за пределы выделенного массива. - В функции
GetIntAsAnsi
есть ошибка в расчете индекса для добавления разделителя. Рассчитывается ((pstr - ansi + 1) % 4 == 0), но нужно ((pstr - ansi + 1) % (4 + 1) == 0). То есть, при расчете необходимо увеличить размер блока на 1, чтобы корректно определять момент добавления разделителя. - В функции
GetIntAsAnsi
есть отсутствие проверки на null-терминатор перед добавлением символа в строку. В результате, если последний символ числа (представляющий собой 0) будет принят за символ разделителя, то будет записано лишнее значение, и строка не будет корректно интерпретироваться как число. - В функции
GetIntAsAnsi
нет обработки случая, когда входное значение равно 0. В этом случае, функция будет пытаться разделить строку, которая состоит только из нулей, что приведет к неопределенному поведению. - В функции
main
нет проверки на то, что функцияGetIntAsAnsi
возвращает корректное значение. Если функция вернет некорректное значение (например, не будет содержать нужного количества символов), то программа может работать некорректно.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д