Path: csiph.com!news.mixmin.net!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Beginner....Decimal/Octal converter help
Date: Sun, 11 Sep 2022 06:37:31 -0700
Organization: A noiseless patient Spider
Lines: 94
Message-ID: <86czc2qbfo.fsf@linuxsc.com>
References: <8ffd982c-2e82-4caa-9256-ec17be2efe56n@googlegroups.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader01.eternal-september.org; posting-host="eacead3a04a98f103c487ee10dc191dc"; logging-data="2034517"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18tMEeB8CgGSgdLF05Alf7oU+Q6ODAnc7U="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:6ecBeNi0G+Gw2skYNvE4tFpjaEQ= sha1:TdYLSnJ9gXdolVFWT0lzG1mEdtc=
Xref: csiph.com comp.lang.c:167600
scott@slp53.sl.home (Scott Lurndal) writes:
> ram@zedat.fu-berlin.de (Stefan Ram) writes:
>
>> ManyBeers writes:
>>
>>> int convertDecimalToOctal(int decimalNumber);
>>
>> The following program tries to convert the number given in main
>> to its octal representation, which is printed to standard output.
>>
>> I wrote it just to the point where it seems to work for this
>> special case, but I'm not convinced that it will print the
>> correct result in all cases or does not overflow any of its
>> buffers!
>>
>> #include
>> #include
>>
>> /* are there digits above 0 in the buffer? */
>> int digits_in( char buffer[] )
>> { size_t i = 0;
>> for( ; i < strlen( buffer )&& buffer[ i ]=='0'; ++i );
>> return buffer[ i ]> '0' && buffer[ i ]<= '9'; }
>>
>> /* write div to "result" and returns the remainder */
>> int divrem
>> ( char dividend[], char result[], int base_of_dividend, int divisor )
>> { { size_t i = 0;
>> for( ; i < strlen( dividend ); ++i )
>> result[ i ]= ' '; result[ i ]= 0; }
>> int r = 0; int j = 0; int k = 0;
>> for( size_t i = 0; i < strlen( dividend ); ++i )
>> { if( dividend[ i ]!= ' ' )
>> { r = r * base_of_dividend + dividend[ i ]- '0';
>> if( r >= divisor )
>> { int const q = r/divisor; r = r%8;
>> result[ j ]=( char )( q + '0' ); }
>> else
>> { result[ j ]='0'; }} ++j; }
>> return r; }
>>
>> /* convert number, which is given in the base_of_dividend into
>> base_of_result */
>> void convert
>> ( char number[], char buffer[],
>> int base_of_dividend,
>> int base_of_result /* must not be larger than base_of_dividend */ )
>> { if( digits_in( number ))
>> { int const digit =
>> divrem( number, buffer, base_of_dividend, base_of_result );
>> { convert( buffer, number, base_of_dividend, base_of_result );
>> putchar( '0' + digit ); }}}
>>
>> int main( void )
>> { /* source in dec */
>> char a[] = "897528309349537459261193475234783479487034102857389475930";
>> /* the buffer must at least have a's len */
>> char b[] = " ";
>> convert( a, b, 10, 8 );
>> putchar( '\n' ); }
>
> Somewhat more concisely:
>
> $ cat /tmp/octal.c
> #include
> #include
> #include
>
>
> int
> main(int argc, const char **argv, const char **envp)
> {
> char buf[64];
> char *bp = &buf[64];
> uint64_t value;
>
> if (argc > 1) value = strtoul(argv[1], NULL, 0);
> else value = 0x400;
>
> *--bp = '\0';
> while (value > 0) {
> *--bp = '0' + (value & 7ul);
> value /= 8;
> }
>
> printf("Octal = %s\n", bp);
> return 0;
> }
This code concisely solves a very different problem. SR's code
is meant to address the problem of converting values that will
not fit in any of C's standard integer types. This code doesn't
even try to do that.