C语言 给定大于 256 的整数,如何在 C 中从整数转换为无符号字符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4629891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:29:05  来源:igfitidea点击:

How to convert from integer to unsigned char in C, given integers larger than 256?

ccastingunsignedintegerchars

提问by Alf_InPogform

As part of my CS course I've been given some functions to use. One of these functions takes a pointer to unsigned chars to write some data to a file (I have to use this function, so I can't just make my own purpose built function that works differently BTW). I need to write an array of integers whose values can be up to 4095 using this function (that only takes unsigned chars).

作为我的 CS 课程的一部分,我获得了一些可以使用的功能。其中一个函数需要一个指向无符号字符的指针来将一些数据写入文件(我必须使用这个函数,所以我不能只制作我自己专门构建的以不同方式工作的函数)。我需要使用此函数(仅采用无符号字符)编写一个整数数组,其值最多可达 4095。

However am I right in thinking that an unsigned char can only have a max value of 256 because it is 1 byte long? I therefore need to use 4 unsigned chars for every integer? But casting doesn't seem to work with larger values for the integer. Does anyone have any idea how best to convert an array of integers to unsigned chars?

但是,我认为 unsigned char 的最大值只能为 256,因为它的长度为 1 个字节,这是否正确?因此,我需要为每个整数使用 4 个无符号字符?但是转换似乎不适用于更大的整数值。有谁知道如何最好地将整数数组转换为无符号字符?

回答by nos

Usually an unsigned char holds 8 bits, with a max value of 255. If you want to know this for your particular compiler, print out CHAR_BIT and UCHAR_MAX from <limits.h>You could extract the individual bytes of a 32 bit int,

通常一个无符号字符包含 8 位,最大值为 255。如果你想知道你的特定编译器的这一点,打印出 CHAR_BIT 和 UCHAR_MAX 从<limits.h>你可以提取 32 位整数的各个字节,

#include <stdint.h>

void
pack32(uint32_t val,uint8_t *dest)
{
        dest[0] = (val & 0xff000000) >> 24;
        dest[1] = (val & 0x00ff0000) >> 16;
        dest[2] = (val & 0x0000ff00) >>  8;
        dest[3] = (val & 0x000000ff)      ;
}


uint32_t
unpack32(uint8_t *src)
{
        uint32_t val;

        val  = src[0] << 24;
        val |= src[1] << 16;
        val |= src[2] <<  8;
        val |= src[3]      ;

        return val;
}

回答by Chris

Unsigned char generally has a value of 1 byte, therefore you can decompose any other type to an array of unsigned chars (eg. for a 4 byte int you can use an array of 4 unsigned chars). Your exercise is probably about generics. You should write the file as a binary file using the fwrite() function, and just write byte after byte in the file.

无符号字符通常具有 1 个字节的值,因此您可以将任何其他类型分解为无符号字符数组(例如,对于 4 字节 int,您可以使用 4 个无符号字符数组)。你的练习可能是关于泛型的。您应该使用 fwrite() 函数将文件写为二进制文件,并在文件中逐个字节地写入。

The following example should write a number (of any data type) to the file. I am not sure if it works since you are forcing the cast to unsigned char * instead of void *.

下面的示例应该将一个数字(任何数据类型)写入文件。我不确定它是否有效,因为您强制强制转换为 unsigned char * 而不是 void *。

int homework(unsigned char *foo, size_t size)
{
    int i;

    // open file for binary writing
    FILE *f = fopen("work.txt", "wb");
    if(f == NULL)
        return 1;

    // should write byte by byte the data to the file
    fwrite(foo+i, sizeof(char), size, f);

    fclose(f);
    return 0;
}

I hope the given example at least gives you a starting point.

我希望给定的例子至少能给你一个起点。

回答by user541686

Yes, you're right; a char/byte only allows up to 8 distinct bits, so that is 2^8 distinct numbers, which is zero to 2^8 - 1, or zero to 255. Do something like this to get the bytes:

你是对的; 一个字符/字节只允许最多 8 个不同的位,因此是 2^8 个不同的数字,即 0 到 2^8 - 1,或 0 到 255。做这样的事情来获取字节:

int x = 0;
char* p = (char*)&x;
for (int i = 0; i < sizeof(x); i++)
{
    //Do something with p[i]
}

(This isn't officially C because of the order of declaration but whatever... it's more readable. :) )

(由于声明的顺序,这不是正式的 C,但无论如何......它更具可读性。:))

Do note that this code may not be portable, since it depends on the processor's internal storage of an int.

请注意,此代码可能不可移植,因为它取决于处理器的内部存储int.

回答by Beerman006

It sounds like what you really want to do is call sprintf to get a string representation of your integers. This is a standard way to convert from a numeric type to its string representation. Something like the following might get you started:

听起来您真正想做的是调用 sprintf 来获取整数的字符串表示形式。这是从数字类型转换为其字符串表示的标准方法。类似以下内容可能会让您入门:

char num[5]; // Room for 4095

// Array is the array of integers, and arrayLen is its length
for (i = 0; i < arrayLen; i++)
{
    sprintf (num, "%d", array[i]);

    // Call your function that expects a pointer to chars
    printfunc (num);
}

回答by dawg

The part of the assignment of: integers whose values can be up to 4095 using this function (that only takes unsigned charsshould be giving you a huge hint. 4095 unsigned is 12 bits.

分配的部分:integers whose values can be up to 4095 using this function (that only takes unsigned chars应该给你一个巨大的提示。4095 unsigned 是 12 位。

You can store the 12 bits in a 16 bit short, but that is somewhat wasteful of space -- you are only using 12 of 16 bits of the short. Since you are dealing with more than 1 byte in the conversion of characters, you may need to deal with endianessof the result. Easiest.

您可以将 12 位存储在 16 位中short,但这有点浪费空间——您只使用了 16 位中的 12 位。由于您在字符转换中处理超过 1 个字节,因此您可能需要处理结果的字节序。最简单。

You could also do a bit field or some packed binary structure if you are concerned about space. More work.

如果你担心空间,你也可以做一个位域或一些压缩的二进制结构。更多的工作。

回答by Clifford

Without information on the function you are directed to use regarding its arguments, return value and semantics (i.e. the definition of its behaviour) it is hard to answer. One possibility is:

如果没有关于您要使用的函数的参数、返回值和语义(即其行为的定义)的信息,就很难回答。一种可能性是:

Given:

鉴于:

void theFunction(unsigned char* data, int size);

then

然后

int array[SIZE_OF_ARRAY];
theFunction((insigned char*)array, sizeof(array));

or

或者

theFunction((insigned char*)array, SIZE_OF_ARRAY * sizeof(*array));

or

或者

theFunction((insigned char*)array, SIZE_OF_ARRAY * sizeof(int));

All of which will pass all of the data to theFunction(), but whether than makes any sense will depend on what theFunction()does.

所有这些都会将所有数据传递给theFunction(),但是否有意义将取决于是什么theFunction()

回答by Martin York

If you have to write an array of integers then just convert the array into a pointer to char then run through the array.

如果您必须编写一个整数数组,则只需将数组转换为指向 char 的指针,然后遍历该数组即可。

int main()
{
    int    data[] = { 1, 2, 3, 4 ,5 };
    size_t size   = sizeof(data)/sizeof(data[0]); // Number of integers.

    unsigned char* out = (unsigned char*)data;
    for(size_t loop =0; loop < (size * sizeof(int)); ++loop)
    {
         MyProfSuperWrite(out + loop);  // Write 1 unsigned char
    }
}

Now people have mentioned that 4096 will fit in less bits than a normal integer. Probably true. Thus you can save space and not write out the top bits of each integer. Personally I think this is notworth the effort. The extra code to write the value and processes the incoming data is not worth the savings you would get (Maybe if the data was the size of the library of congress). Rule one do as little work as possible (its easier to maintain). Rule two optimize if asked (but ask why first). You may save space but it will cost in processing time and maintenance costs.

现在人们已经提到 4096 比普通整数适合的位数更少。可能是真的。因此,您可以节省空间而不用写出每个整数的最高位。我个人认为这是值得的。写入值和处理传入数据的额外代码不值得您节省(也许如果数据是国会图书馆的大小)。规则一做尽可能少的工作(它更容易维护)。规则二优化,如果问(但先问为什么)。您可以节省空间,但会增加处理时间和维护成本。