3

I have an array of characters like:

char bytes[8]={2,0,1,3,0,8,1,9}

I want to take the first four chars from this array below, and put them into a new integer variable. How can I do this? I am trying to shift them, but this logic is not working. Any idea? Thanks.

Example: from this array to get: year month day

char bytes[8]={2,0,1,3,0,8,1,9}

int year = 2013 ......  month = 8 ............  day = 19
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    Please show the code you have that doesn't work (that is, the "I am trying to shift them, but this logic is not working") code. This is very simple, and if I just tell you how to do it, it won't help you understand. – zwol Aug 19 '13 at 18:41
  • So, what exactly have you tried? This is easy if you think a bit about it. –  Aug 19 '13 at 18:42
  • 1
    http://stackoverflow.com/questions/868496/how-to-convert-char-to-integer-in-c – user2485710 Aug 19 '13 at 18:42
  • also note that most of the time a `char` is nothing more than an `unsigned int` – user2485710 Aug 19 '13 at 18:45
  • 2
    @user2485710 No, it isn't. A `char` is a `char` and nothing else. –  Aug 19 '13 at 18:46
  • 1
    First, those aren't ascii chars, they're simple integers (and one of them is a null-char at that). If that was intended, the answer to your question is simply apply what you no-doubt learned in elementary school. 2013 is 2*1000 + 0*100 + 1*10 + 3*1. hmmm. I see a pattern here. – WhozCraig Aug 19 '13 at 18:46
  • @H2CO3, you are being too literal and adamant. chars and ints can be treated synonymously. This is one of the fundamental aspects of C. – JackCColeman Aug 19 '13 at 18:49
  • 1
    @JackCColeman Don't teach me C. You are talking about the fact that `char` is an integral type, and it can be implicitly converted from and to other integral types. This does **not** mean that "`char` is an `unsigned int`", because it isn't. –  Aug 19 '13 at 18:50
  • 3
    @JackCColeman a `char` is an *integer-type* per the standard. So is an `int`. But that's long way off from saying an `int` and a `char` are synonymous. That would be like saying an apple is a fruit, and so is an orange, so apples are oranges (which reminds me, its lunchtime here). – WhozCraig Aug 19 '13 at 18:52
  • @WhozCraig, the word for orange came into usage because people initially thought that it was an apple only colored orange. – JackCColeman Aug 19 '13 at 19:15
  • @JackCColeman That's *awesome* (true or not, I *have* to remember that =). Thanks! – WhozCraig Aug 19 '13 at 20:13

6 Answers6

6

Instead of left shifting with << operator (which is more or less equivalent to multiplying by 2^N), you should rather multiply by 10^N. Here is how you can do:

int year = bytes[0] * 1000 +
           bytes[1] * 100 +
           bytes[2] * 10 +
           bytes[3];

int month = bytes[4] * 10 +
            bytes[5];

int day = bytes[6] * 10 +
          bytes[7];

Of course, you can use loops to make your code more readable (if necessary).

enum {
   NB_DIGITS_YEAR = 4,
   NB_DIGITS_MONTH = 2,
   NB_DIGITS_DAY = 2,
   DATE_SIZE = NB_DIGITS_YEAR + NB_DIGITS_MONTH + NB_DIGITS_DAY
};

struct Date {
   int year, month, day;
};

int getDateElement(char *bytes, int offset, int size) {
   int power = 1;
   int element = 0;
   int i;

   for (i = size - 1; i >= 0; i--) {
      element += bytes[i + offset] * power;
      power *= 10;
   }

   return element;
}

struct Date getDate(char *bytes) {
   struct Date result;
   result.year = getDateElement(bytes, 0, NB_DIGITS_YEAR);
   result.month = getDateElement(bytes, NB_DIGITS_YEAR, NB_DIGITS_MONTH);
   result.day = getDateElement(bytes, NB_DIGITS_YEAR + NB_DIGITS_MONTH, NB_DIGITS_DAY);
   return result;
}

With this last code it is easier to change the format of the date stored in bytes.

Example:

int main(void) {
   char bytes[DATE_SIZE] = {2, 0, 1, 3, 0, 8, 1, 9};
   struct Date result = getDate(bytes);
   printf("%02d/%02d/%04d\n", result.day, result.month, result.year);
   return 0;
}

Output:

19/08/2013
md5
  • 23,373
  • 3
  • 44
  • 93
  • another problem my value is in decimal!! example: char bytes[8]={50,48,49,51,50...... how to convert decimal to character? – Шијаковски Глигор Aug 20 '13 at 08:23
  • @ШијаковскиГлигор: You just have to substract `'0'`. See [here](http://stackoverflow.com/questions/17320769/convert-int-to-char-without-using-ascii/17320787#17320787). – md5 Aug 20 '13 at 09:54
4

Do you want this?

int year  = byte[0] * 1000 + byte[1] * 100 + byte[2] * 10 + byte[3];
int mounth = byte[4] * 10 + byte[5];
int day =  byte[6] * 10 + byte[7];

Note: This works because the integers are actual digit values, not the character codes of the digits like e.g byte[] value at index=0 is 2 but not '2'.

So suppose if you have array of char values like:

char bytes[8]={'2', '0', '1', '3', '0', '8', '1', '9'};

Then change this code like:

#define digit(d)  ((d) - ('0'))

int year  =  digit(byte[0]) * 1000 + 
             digit(byte[1]) * 100 + 
             digit(byte[2]) * 10 + 
             digit(byte[3]);
int mounth = digit(byte[4]) * 10 + digit(byte[5]);
int day =  digit(byte[6]) * 10 + digit(byte[7]);
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • `'2'` is an integer constant. This is not precise phrasing. Better: "This works because the integers are actual digit values, not the character codes of the digits". –  Aug 19 '13 at 19:02
  • @H2CO3 yes I know in C '2' is int constant – Grijesh Chauhan Aug 19 '13 at 19:03
  • @H2CO3 Thanks for I copy yuor comment :) – Grijesh Chauhan Aug 19 '13 at 19:05
  • @haccks In **C** (not in C++) try `sizeof('a')`, `sizeof(int)`, `sizeof(char)`. I written that `'2'` is char constant that is technically incorrect (because its `int` not `char`!). Also a C implementation free to use any encoding (not only ASCII) so H2CO3 writes **character codes** of the digits. – Grijesh Chauhan Aug 19 '13 at 19:17
  • @haccks every one is learning, every one have questions. Today H2CO3 asked a question that is out-of-my understanding :P – Grijesh Chauhan Aug 19 '13 at 19:21
3

Start with zero. Add the first digit. Multiply with ten. Add the second digit. Multiply by ten. Add the third digit. Multiply by ten. Add the fourth digit. Now you have a four digit integer.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

I am unfamiliar with specific c syntax, but I can convey the idea. Concatenate the chars together to form a string, and then use a parseInt method (assuming c has one) to get an integer from that. Alternatively, you could shift the characters through multiplication by powers of 10. For example, given {2,0,1,3}: (2 * 10^3) + (0 * 10^2) + (1 * 10^1) + (3 * 10^0)

haccks
  • 104,019
  • 25
  • 176
  • 264
Paris Nelson
  • 131
  • 6
0

Something like this will work:

 int month;
 int year;
 int year = ((int)bytes[0]*1000);
 year += (int)bytes[1]*100);
 year += ((int)bytes[2] *10);
 year += ((int)bytes[3]);

 if(sizeof(bytes) == 9){ 
  //month is >10
   month = ((int)bytes[4] *10);
   month += ((int)bytes[5]);
}

..etc

Scotty Bauer
  • 1,277
  • 9
  • 14
0

Here is another way to do this, largely using string functions from the standard library.

I haven't tested this code, but it should give you an idea.

    #include <string.h>
    int main (void) {
      char bytes[8]={2,0,1,3,0,8,1,9};
      char tempstring[8], * end;
      unsigned int i, year, month, day;
      char zero = "0"; //we need to know the difference between 0 and "0"
      for (i = 0; i < 8; i++) {
        bytes[i] += (int)zero;
      }
  //now the numbers are the equivalent characters, but we need to split them out
  //and convert them 
  strncopy(tempstring, bytes, 4);
  year = strtoul(tempstring, &end, 10);
  strncopy(tempstring , bytes + 4, 2);
  month = strtoul(tempstring, &end, 10);
  strncopy(tempstring , bytes + 6, 2);
  day = strtoul(tempstring, &end, 10);

  return 0;
  }
lsiebert
  • 667
  • 1
  • 5
  • 16