在C语言中从字符数组中获取整数值

3

I have an array of characters like:

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

我想从以下数组中获取前四个字符,并将它们放入一个新的整数变量中。我该如何做到这一点?我正在尝试移位,但这种逻辑不起作用。有什么建议吗?谢谢。
例如:从这个数组中获取:年份 月份 日
char bytes[8]={2,0,1,3,0,8,1,9}

int year = 2013 ......  month = 8 ............  day = 19

1
请展示你的代码,说明哪里出了问题(也就是,“我试图移位它们,但这个逻辑不起作用”)。这很简单,如果我只是告诉你如何做,那么这并不能帮助你理解。 - zwol
1
https://dev59.com/qHNA5IYBdhLWcg3wrf43 - user2485710
2
@user2485710 不是这样。char 就是 char,没有别的。 - user529758
1
@JackCColeman 不要教我C语言。你说的是char是一种整型,它可以隐式地转换为其他整型,但这并不意味着"char是一个unsigned int",因为它不是。 - user529758
3
@JackCColeman,“char”根据标准是一种整数类型,同样适用于“int”。但这远远不能说明“int”和“char”是同义词。这就像说苹果是水果,橙子也是水果,所以苹果就是橙子一样(这提醒我,现在是午餐时间)。 - WhozCraig
显示剩余6条评论
6个回答

6

不要使用“<<”操作符进行左移(它大体上等同于将其乘以“2^N”),而应该使用“10^N”进行乘法运算。以下是如何操作:

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

当然,如果必要的话,您可以使用循环来使您的代码更易读。
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;
}

使用这段代码,更改存储在 bytes 中的日期格式变得更加容易。

示例:

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

输出:

19/08/2013

另一个问题是我的值是十进制的!例如:char bytes [8] = {50,48,49,51,50......如何将十进制转换为字符? - Шијаковски Глигор
@ШијаковскиГлигор:你只需要减去 '0'。请参见这里 - md5

4

你需要这个吗?

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

注意:这是因为整数是实际的数字值,而不是像byte[]中索引为 0 的字符代码(例如 '2')。

因此,假设您有一个字符值数组:

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

然后将这段代码更改为:

#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]);

“'2'”是一个整数常量。这不是精确的措辞。更好的说法是:“这是因为整数是实际的数字值,而不是数字的字符代码。” - user529758
@H2CO3 是的,我知道在C语言中,'2'是整数常量。 - Grijesh Chauhan
@H2CO3 谢谢你,我复制了你的评论 :) - Grijesh Chauhan
在C语言中(而不是C++),尝试sizeof('a')sizeof(int)sizeof(char)。我写过'2'是字符常量,但从技术上讲这是不正确的(因为它是int而不是char!)。此外,C实现可以使用任何编码(不仅仅是ASCII),所以H2CO3写入数字的字符代码 - Grijesh Chauhan
@haccks 每个人都在学习,每个人都有问题。今天H2CO3问了一个我不理解的问题:P - Grijesh Chauhan

3
从零开始。加上第一个数字。乘以十。再加上第二个数字。再乘以十。再加上第三个数字。再乘以十。最后加上第四个数字。现在你就拥有了一个四位整数。

2
@Magn3s1um 当数据不是实际可打印字符时,就不能这样做。再看一下OP的数组初始化列表。 - WhozCraig
@WhozCraig,另外,0终止符丢失了。 - user529758
1
@H2CO3 哦,那里有一个,但我不认为它是故意的 =) - WhozCraig

1
我不太熟悉C语言的具体语法,但我可以传达这个想法。将字符拼接在一起形成一个字符串,然后使用parseInt方法(假设C有这样一个方法)从中获取整数。或者,您可以通过乘以10的幂来通过移位字符。例如,给定{2,0,1,3}(2 * 10^3) + (0 * 10^2) + (1 * 10^1) + (3 * 10^0)

0

类似如下代码将能够运行:

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

...等等


0

这里有另一种方法来完成这个任务,主要使用标准库中的字符串函数。

我没有测试过这段代码,但它应该能给你一个想法。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接