-1

I'm looking for a simple way in C to convert an string to a byte or binary (8 bit). I'm always going to receive a string between 0 and 255, for example:

  • If I receive "0", I want to convert it to 00000000
  • If I receive "255", I want to convert it to 11111111
  • If I receive "128", I want to convert it to 10000000

This would be useful for me because I'm implementing code in C for a PIC16F1705 where depending on a value I receive via the EUSART module I will put this value in the PWM module to control the power of a DC motor. I'm using the MPLAB IDE and the XC8 compiler in order to be able to use C rather than assembly.

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 1
    Possible duplicate of [Convert decimal to binary in C](http://stackoverflow.com/questions/14280336/convert-decimal-to-binary-in-c) – MikeCAT Nov 26 '15 at 14:10
  • 1
    @MikeCAT: I don't think thats the right duplicate for this question (although it's not entirely clear from the OP's wording exactly what they want, admittedly). – Paul R Nov 26 '15 at 14:15

1 Answers1

3

You can just use atoi for this, e.g.

#include <stdlib.h>

const char *s = "192";
uint8_t val = atoi(s);  // val = 192 = 11000000


If you want to avoid pulling in library code though you could always roll your own custom version of atoi for this specific use case, e.g.:
uint8_t atoi_u8(const char *p)
{
    uint8_t v = 0;
    while (*p)
    {
        v = v * 10 + *p - '0';
        p++;
    }
    return v;
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 1
    Sir, if you don't mind me asking, `atoi()` won't be able to differenciate between the number 0 and a fault, so isn't it kind of better to use `strtol()`? – Sourav Ghosh Nov 26 '15 at 14:16
  • 1
    @SouravGhosh: since the OP is working with a PIC, I went for a simple, lightweight solution, but if robustness might be a problem then they can always parse the input string to make sure it's valid first. – Paul R Nov 26 '15 at 14:18
  • 1
    @SouravGhosh Also OP said he/she assumes to always receive a string ranging from 0 to 255, inclusive. – Neijwiert Nov 26 '15 at 14:19
  • @PaulR atoi most likely calls strtol internally, so it is hard to see how atoi would be lightweight. – Lundin Nov 26 '15 at 14:20
  • 2
    @Lundin Where are you basing that information on? I don't think it does. cplusplus.com states it causes undefined behavior when it overflows. – Neijwiert Nov 26 '15 at 14:21
  • 1
    @Lundin: I'm not familiar with the PIC libraries, but I would have thought that they would be tailored for small code size. – Paul R Nov 26 '15 at 14:21
  • @Neijwiert ISO 9899:2011 7.22.1.2/2. "The atoi, atol, and atoll functions convert the initial portion of the string pointed to by nptr to int, long int, and long long int representation, respectively. Except for the behavior on error, they are equivalent to `atoi: (int)strtol(nptr, (char **)NULL, 10` ". Note that calling strtol() internally doesn't make behavior upon error any more or less defined. – Lundin Nov 26 '15 at 14:25
  • 2
    @Lundin that doesn't prohibit an atoi implementation which is smaller than strtol. – greggo Nov 26 '15 at 14:27
  • You might want to leave a word on masking to find single bits are set or not. – alk Nov 26 '15 at 14:29
  • @greggo Actually it does, because according to the above, atoi _must_ process the integer as if it was of type `long` and then afterwards truncate it to type `int`. Though of course if the compiler can tell that the long will not make any difference to the answer, it might optimize the library code. – Lundin Nov 26 '15 at 14:30
  • 1
    @lundin: "except for the behaviour on error" is a pretty big out :) – rici Nov 26 '15 at 14:39
  • 1
    @Lundin assume int = 16, long =32 bits. atoi can be implemented without performing any 32-bit computations. The lower 16 bit of the strtol result is the same as what you get by discarding the overflow in the 16-bit *10 and add. Bear in mind that each 32-bit op may well be a function call on a pic. – greggo Nov 26 '15 at 14:39
  • @rici I read it that if strol doesn't overflow, atoi's behaviour must comply by returning the conversion to int of the proper long result. This still allows a simple implementation that just does `acc = acc*10+(digit-'0')` using `unsigned acc`. – greggo Nov 26 '15 at 14:45
  • 1
    @greggo "If the value of the result cannot be represented, the behavior is undefined." No requirement for compliance on too-large values. Quote is from the start of 7.22.1 – rici Nov 26 '15 at 14:54
  • @Lundin put it another way, if the compiler is allowed to optimize the library code in this way, the programmer of the library code is allowed, no? – greggo Nov 26 '15 at 14:55
  • @rici I see your point now, i.e. 'except for behaviour on error' encompasses the overflow error in atoi, not just the detected error in strtol. – greggo Nov 26 '15 at 15:02