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
11
  • 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. Commented Aug 19, 2013 at 18:41
  • 1
    stackoverflow.com/questions/868496/… Commented Aug 19, 2013 at 18:42
  • 2
    @user2485710 No, it isn't. A char is a char and nothing else. Commented Aug 19, 2013 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. Commented Aug 19, 2013 at 18:46
  • 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). Commented Aug 19, 2013 at 18:52

6 Answers 6

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
Sign up to request clarification or add additional context in comments.

2 Comments

another problem my value is in decimal!! example: char bytes[8]={50,48,49,51,50...... how to convert decimal to character?
@ШијаковскиГлигор: You just have to substract '0'. See here.
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]);

5 Comments

'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".
@H2CO3 yes I know in C '2' is int constant
@H2CO3 Thanks for I copy yuor comment :)
@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.
@haccks every one is learning, every one have questions. Today H2CO3 asked a question that is out-of-my understanding :P
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.

3 Comments

@Magn3s1um not when the data isn't actual printable characters. Look at the OP's array initializer list again.
@WhozCraig Also, the 0-terminator is missing.
@H2CO3 oh there's one in there, but I don't think it intended to be one =)
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)

Comments

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

Comments

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;
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.