Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This code has problems:</p> <pre><code>while(c = getchar() != '\n' &amp;&amp; c != EOF) </code></pre> <p>Not enough parentheses — assignment is a low priority operator. It should be:</p> <pre><code>while ((c = getchar()) != '\n' &amp;&amp; c != EOF) </code></pre> <p>Another set of problems is in the conversion code in the body of the loop:</p> <pre><code> if (c &gt;= 97) c = c - 'a' - 1; else c = c; numdec += numdec * base + c; </code></pre> <p>The choice of <code>97</code> is presumably the ASCII or ISO 8859-<em>n</em> or Unicode code point for <code>a</code>. This ignores upper case letters, punctuation, and treats the digits <code>0</code> to <code>9</code> as though they 48..57. You probably need to use <code>#include &lt;ctype.h&gt;</code>. It also does not validate that the 'digit' is valid for the base.</p> <p>However, on the first call to <code>intToDec()</code>, the first character read is a newline, left over by <code>scanf()</code>, so the first number is always zero, if you enter the numbers one per line as you're told to.</p> <p>When you finally get to <code>outToDec()</code>, you have some interesting numerology. I added <code>printf()</code> statements to track function entry and exit, and also for key points in the loop:</p> <pre><code>void outFromDec(int num, int base) { printf("--&gt;&gt; %s: %d %d\n", __func__, num, base); int count = 0, temp = num, i; char c; while (temp != 0) { temp /= base; count++; } printf("Count: %d\n", count); temp = num; do { printf("count: %d; temp = %d\n", count, temp); for (i = 1; i &lt; count; i++) temp /= base; if (temp &lt;= 9) c = '0' + temp; else c = 'a' + temp - 1; putchar(c); count--; temp = num / temp; } while (temp != 0); printf("&lt;&lt;-- %s\n", __func__); } </code></pre> <p>The <code>__func__</code> is a predefined identifier in C99 containing the function name. It may not be available to you in MSVC; if not, replace it with the function name.</p> <p>For the inputs <code>1</code>, <code>9</code>, <code>9</code>, the output from the program was:</p> <pre><code>--&gt;&gt; inToDec: 9 &lt;&lt;-- inToDec: 0 --&gt;&gt; inToDec: 9 &lt;&lt;-- inToDec: 57 --&gt;&gt; outFromDec: 57 9 Count: 2 count: 2; temp = 57 6count: 1; temp = 9 9count: 0; temp = 6 6count: -1; temp = 9 9count: -2; temp = 6 </code></pre> <p>And the count continued to decrease and the 6's and 9's continued to alternate. You seem to be trying to isolate the digits with the most significant digit (MSD) discovered first. The loop determining <code>count</code> is correct; the loop printing the digits clearly isn't. You should be able to take it from there; it is routine debugging. Note how I used the print statements to see what was going on. If you can't resolve it by just looking at the code, print out the result of every expression, if necessary.</p> <p>I observe that to print 57 in base 10, you'd discover that there are 2 digits to print (<code>count == 2</code>). The first digit would be found by dividing by the base (10) <code>count-1</code> times; this would give you 5 to print. You probably need to subtract 5 * 10 from the number so that the next (in this case, the last) time around the loop, you'd start with just 7, which you'd print. The loop would stop. You should ensure the loop breaks if <code>count</code> ever goes negative.</p> <p>This is an expensive way of formatting a 10-digit 32-bit number (or even more so a 19-digit 64-bit number). It can be made to work, though. The standard procedure collects the digits in reverse order and arranges to print them out in the inverse order. (<code>number % base</code> gives you the digit to be printed; <code>number /= base</code> reduces the number of digits left to process.)</p> <hr> <p>As happens quite often, the OP is under artificial constraints and may not use strings. Yuck!</p> <p>Here is a 'read an integer' function that is plausibly robust. It does assume 2's complement arithmetic; it contains an assertion that should fire if it was ever run on a machine that was sign-magnitude or 1's complement (but I haven't tested it; I don't have any such machines available to test on).</p> <p>Note that the code accumulates the number as a negative number, and makes it positive at the end if it should be positive. This makes it easier to deal with INT_MIN than trying to accumulate it as a positive <code>int</code>.</p> <p>For the purposes of the exercise, I'm treating the system as though <code>sizeof(intmax_t) == sizeof(int)</code> (and hence <code>sizeof(int) == sizeof(long)</code> and <code>sizeof(int) == sizeof(long long)</code> too); this technique would work if the integer type were <code>intmax_t</code> instead of <code>int</code>. Note that the C standard does not rule out this supposed configuration (but the standard requires that <code>CHAR_BIT * sizeof(int) &gt;= 64</code> to be a conforming implementation).</p> <pre><code>#include &lt;assert.h&gt; #include &lt;ctype.h&gt; #include &lt;limits.h&gt; #include &lt;stdio.h&gt; /* Read an integer from stdin without prompt: code is not allowed to use strings! */ enum { E_OK = 0, E_EOF = -1, E_INVCHAR = -2, E_OVERFLOW = -3 }; extern int read_an_int(int *value); int read_an_int(int *value) { int number = 0; int c; int pos_neg = +1; assert(-INT_MAX != INT_MIN); // Probably 2's complement while ((c = getchar()) != EOF &amp;&amp; isspace(c)) ; if (c == '-') { pos_neg = -1; c = getchar(); } else if (c == '+') { pos_neg = +1; c = getchar(); } if (c == EOF) return E_EOF; if (!isdigit(c)) return E_INVCHAR; number = '0' - c; /* Negated digit */ while ((c = getchar()) != EOF &amp;&amp; isdigit(c)) { int d = '0' - c; /* Negated digit */ if (number &lt; INT_MIN / 10 || (number == INT_MIN/10 &amp;&amp; d &lt; INT_MIN % 10)) return E_OVERFLOW; //printf("N1 %d; d %d; ", number, d); number = number * 10 + d; //printf("N2 %d\n", number); } if (c != EOF) ungetc(c, stdin); if (pos_neg != -1) { //printf("Should be switched (%d)(%d)\n", pos_neg, number); if (number == INT_MIN) return E_OVERFLOW; number = -number; //printf("Should be positive (%d)(%d)\n", pos_neg, number); } *value = number; return E_OK; } static void gobble_input(void) { int c; while ((c = getchar()) != EOF) { if (isdigit(c) || c == '+' || c == '-') { ungetc(c, stdin); break; } printf("Skip %c\n", c); } } int main(void) { int rc; int number; while ((rc = read_an_int(&amp;number)) != E_EOF) { switch (rc) { case E_INVCHAR: printf("Invalid character spotted\n"); gobble_input(); break; case E_OVERFLOW: printf("Input would have overflowed integer range %d..%d\n", INT_MIN, INT_MAX); break; case E_OK: printf("Input number: %d\n", number); break; default: assert(0); break; } } return 0; } </code></pre> <p>The test data file I used was:</p> <pre><code>0 1 2 3 4 5 6 7 8 9 11 +123 1234 56789 +123456789 2147483647 2147483648 +000000123456789 000000123456789 -0000 +0000 -1 -2 -9 -21 -321 -4321 -2147483647 -2147483648 -2147483649 # Bogus data or partially bogus data - + -213a +213a +.213 3.14159E+23 </code></pre> <p>The output from that was:</p> <pre><code>Input number: 0 Input number: 1 Input number: 2 Input number: 3 Input number: 4 Input number: 5 Input number: 6 Input number: 7 Input number: 8 Input number: 9 Input number: 11 Input number: 123 Input number: 1234 Input number: 56789 Input number: 123456789 Input number: 2147483647 Input would have overflowed integer range -2147483648..2147483647 Input number: 123456789 Input number: 123456789 Input number: 0 Input number: 0 Input number: -1 Input number: -2 Input number: -9 Input number: -21 Input number: -321 Input number: -4321 Input number: -2147483647 Input number: -2147483648 Input would have overflowed integer range -2147483648..2147483647 Invalid character spotted Skip Skip B Skip o Skip g Skip u Skip s Skip Skip d Skip a Skip t Skip a Skip Skip o Skip r Skip Skip p Skip a Skip r Skip t Skip i Skip a Skip l Skip l Skip y Skip Skip b Skip o Skip g Skip u Skip s Skip Skip d Skip a Skip t Skip a Skip Invalid character spotted Invalid character spotted Input number: -213 Invalid character spotted Skip Input number: 213 Invalid character spotted Skip Invalid character spotted Input number: 213 Input number: 3 Invalid character spotted Input number: 14159 Invalid character spotted Input number: 23 </code></pre> <p>Note that the last line provided 3 valid numbers (and two invalid characters, the <code>.</code> and the <code>E</code>).</p> <p>It isn't particularly easy; that's why these things are coded in library functions. Also, the 'no strings' requirement means I can't do decent error reporting when there are invalid characters or overflows.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload