Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将十六进制字符IP转换为二进制_C - Fatal编程技术网

C 将十六进制字符IP转换为二进制

C 将十六进制字符IP转换为二进制,c,C,几天前我问了一个问题,这对我帮助很大,但我又有一个问题。我没有得到的是,当我得到十六进制输入作为scanf%c%c.%c%c.%c%c.%c%c时,如何将其转换为二进制。我想说的是,假设输入为00.11.10.FF,我如何将其转换为00000000.00010001.00010000.11111111,并像这样打印 如果您能帮助我,我将非常高兴。如果您仍有问题,如注释中所述,除非您想创建一个查找表,这是一个很好的方法,否则您的第一个任务是将ASCII字符00.11.10.FF转换为0x0、0x1

几天前我问了一个问题,这对我帮助很大,但我又有一个问题。我没有得到的是,当我得到十六进制输入作为scanf%c%c.%c%c.%c%c.%c%c时,如何将其转换为二进制。我想说的是,假设输入为00.11.10.FF,我如何将其转换为00000000.00010001.00010000.11111111,并像这样打印


如果您能帮助我,我将非常高兴。

如果您仍有问题,如注释中所述,除非您想创建一个查找表,这是一个很好的方法,否则您的第一个任务是将ASCII字符00.11.10.FF转换为0x0、0x11、0x10和0xff的实际数值。有很多方法可以做到这一点,但是如果您使用scanf进行阅读,您也可以让scanf通过使用%x格式说明符进行阅读,该说明符将接受十六进制字符并执行转换

例如,要将每个四边形读入名为hex的无符号值数组,可以执行以下操作:

#define QUAD  4u    /* if you need a constant, #define one (or more) */
...
    unsigned hex[QUAD] = {0};   /* let's input the values as numbers */
    ...
    if (scanf ("%x.%x.%x.%x", &hex[0], &hex[1], &hex[2], &hex[3]) != 4) {
        fputs ("error: invalid input.\n", stderr);
        return 1;
    }
#include <stdio.h>
#include <limits.h>

#define QUAD  4u    /* if you need a constant, #define one (or more) */
#define QBITS 8u

/** binary representation of 'v' padded to 'sz' bits.
 *  the padding amount is limited to the number of
 *  bits in 'v'. valid range: 0 - sizeof v * CHAR_BIT.
 */
void binprnpad (const unsigned long v, size_t sz)
{
    if (!sz) { fprintf (stderr, "error: invalid sz.\n"); return; }
    if (!v)  { while (sz--) putchar ('0'); return; }

    if (sz > sizeof v * CHAR_BIT)
        sz = sizeof v * CHAR_BIT;

    while (sz--)
        putchar ((v >> sz & 1) ? '1' : '0');
}

int main (void) {

    unsigned hex[QUAD] = {0};   /* let's input the values as numbers */

    fputs ("enter hex IP: ", stdout);   /* read/validate input */
    if (scanf ("%x.%x.%x.%x", &hex[0], &hex[1], &hex[2], &hex[3]) != 4) {
        fputs ("error: invalid input.\n", stderr);
        return 1;
    }

    for (unsigned i = 0; i < QUAD; i++) {   /* loop over each quad */
        if (i)                      /* if not zero output the '.' */
            putchar ('.');
        binprnpad (hex[i], QBITS);  /* output the 8-bits per quad */
    }
    putchar ('\n');     /* tidy up with newline */

    return 0;
}
注意:您可以将十六进制声明为unsigned char并保存额外的字节,但是您可能希望使用hh type修饰符限制scanf读取的值,例如%hhx,但旧版本的VS不支持该前缀,因此在这种情况下,将使用简单的unsigned

将十六进制字符转换为数值后,剩下的就是输出每个字符的二进制表示,即已存储在内存中的值。为此,您可以简单地循环和移位,检查位是0还是1,并输出相应的字符“0”或“1”

此外,由于一个简单的循环和移位将只输出到没有更多的1位为止,因此您需要设置要显示的位数,以确保通过循环该次数获得完整的8个字节。将请求位数的信息写入标准输出的便捷功能可以是:

/** binary representation of 'v' padded to 'sz' bits.
 *  the padding amount is limited to the number of
 *  bits in 'v'. valid range: 1 - sizeof v * CHAR_BIT.
 */
void binprnpad (const unsigned long v, size_t sz)
{
    if (!sz) { fprintf (stderr, "error: invalid sz.\n"); return; }
    if (!v)  { while (sz--) putchar ('0'); return; }

    if (sz > sizeof v * CHAR_BIT)
        sz = sizeof v * CHAR_BIT;

    while (sz--)
        putchar ((v >> sz & 1) ? '1' : '0');
}
CHAR_BIT是一个宏,表示每个字节的位数,位于limits.h中

总而言之,你可以做到:

#define QUAD  4u    /* if you need a constant, #define one (or more) */
...
    unsigned hex[QUAD] = {0};   /* let's input the values as numbers */
    ...
    if (scanf ("%x.%x.%x.%x", &hex[0], &hex[1], &hex[2], &hex[3]) != 4) {
        fputs ("error: invalid input.\n", stderr);
        return 1;
    }
#include <stdio.h>
#include <limits.h>

#define QUAD  4u    /* if you need a constant, #define one (or more) */
#define QBITS 8u

/** binary representation of 'v' padded to 'sz' bits.
 *  the padding amount is limited to the number of
 *  bits in 'v'. valid range: 0 - sizeof v * CHAR_BIT.
 */
void binprnpad (const unsigned long v, size_t sz)
{
    if (!sz) { fprintf (stderr, "error: invalid sz.\n"); return; }
    if (!v)  { while (sz--) putchar ('0'); return; }

    if (sz > sizeof v * CHAR_BIT)
        sz = sizeof v * CHAR_BIT;

    while (sz--)
        putchar ((v >> sz & 1) ? '1' : '0');
}

int main (void) {

    unsigned hex[QUAD] = {0};   /* let's input the values as numbers */

    fputs ("enter hex IP: ", stdout);   /* read/validate input */
    if (scanf ("%x.%x.%x.%x", &hex[0], &hex[1], &hex[2], &hex[3]) != 4) {
        fputs ("error: invalid input.\n", stderr);
        return 1;
    }

    for (unsigned i = 0; i < QUAD; i++) {   /* loop over each quad */
        if (i)                      /* if not zero output the '.' */
            putchar ('.');
        binprnpad (hex[i], QBITS);  /* output the 8-bits per quad */
    }
    putchar ('\n');     /* tidy up with newline */

    return 0;
}
只读字符-查找表方法

如果您只能读取字符,而无法读入数组或字符串,那么最简单的方法就是简单地读取字符,并从一个简单的表中查找其二进制表示形式,该表包含0-15或[0-9A-F]的二进制表示形式

查找表可以是一个简单的全局表,例如

/* lookup table for hex byte binary representations */
char *lookup[] = {  "0000", "0001", "0010", "0011", 
                    "0100", "0101", "0110", "0111", 
                    "1000", "1001", "1010", "1011",
                    "1100", "1101", "1110", "1111"  };
然后,该方案是直接的,从用户处读取一个字符,如果字符c是0-9,只需输出查找[c-'0'],其中c-'0'产生数字0-9,请参见:。如果字符c是[A-F],则输出查找[c-'7'],该查找将ASCII字符值'7'减去到查找表中的索引10-15。否则,如果字符是“.”,只需将其原封不动地输出即可

为了防止有人输入00.11.10.ff,只需使用ctype.h中提供的toupper将读取的所有字符转换为uppper大小写,或手动清除所有[a-f]中的第6位

这很简单。您甚至不需要scanf,只需要getchar;,e、 g

小写十六进制示例:

$ ./bin/hexip2bin
enter hex IP: 00.11.10.ff
00000000.00010001.00010000.11111111
读取一个字符并输出一个半字节

当然,你也可以在不同的方法之间进行混合和匹配。如果不能使用查找表,则只需获取字符的数值,并将表示该十六进制值的4位写入输出,例如

#include <stdio.h>
#include <limits.h>
#include <ctype.h>

#define QUAD  4u    /* if you need a constant, #define one (or more) */
#define QBYTES 8u

/** binary representation of 'v' padded to 'sz' bits.
 *  the padding amount is limited to the number of
 *  bits in 'v'. valid range: 1 - sizeof v * CHAR_BIT.
 */
void binprnpad (const unsigned long v, size_t sz)
{
    if (!sz) { fprintf (stderr, "error: invalid sz.\n"); return; }
    if (!v)  { while (sz--) putchar ('0'); return; }

    if (sz > sizeof v * CHAR_BIT)
        sz = sizeof v * CHAR_BIT;

    while (sz--)
        putchar ((v >> sz & 1) ? '1' : '0');
}

int main (void) {

    unsigned ndx = 0;   /* index of the hex byte read */

    fputs ("enter hex IP: ", stdout);   /* read/validate input */

    while (ndx < QBYTES) {  /* read until 8 hex bytes read */
        unsigned char c = toupper(getchar());   /* read char as upper-case */
        if (isdigit (c)) {                      /* if [0-9] */
            binprnpad (c - '0', QUAD);
            ndx++;
        }
        else if (isxdigit (c)) {                /* if [A-F] */
            binprnpad (c - '7', QUAD);
            ndx++;
        }
        else if (c == '.')                      /* if '.' */
            putchar (c);
        else {      /* handle character not [0-9A-F.] */
            fputs ("(error: invalid character input)\n", stderr);
            break;
        }
    }
    putchar ('\n');     /* tidy up with newline */

    return 0;
}
输出相同


这只是给同一只猫剥皮的另一种方式。仔细检查一下,如果您还有其他问题,请告诉我。

Hex->binary非常简单。每个十六进制数字正好转换成4个二进制位。所以我基本上取每个变量并转换它们。但这需要大量的if语句,对吗?首先,当你阅读%c%c时,你会明白。。。。您读取的是ASCII字符而不是数字,因此必须首先将ASCII字符[0-9A-F]转换为相应的数值。一旦你有了十进制表示法,二进制就已经存储在内存中了。或者,您可以编写一个查找表,直接从ASCII转换为该字符的二进制表示形式-由您决定。可能重复的嘿,谢谢您的回答!但问题是我不太了解他们,因为我们还没有学会他们。我之所以使用%c进行输入,是因为讲师说我们不能像我说的那样使用%x数组来存储值和字符串,因为我们还没有学习它们。这是我在计算机工程专业的第一年,这是一项c编程语言的作业。很抱歉,我应该把它写在主要的帖子里。好的,我可以帮你,我会添加一个。你应该为你的教授额外的不必要的工作打耳光:谢谢你这么详细的解释。这对我会很有帮助的。虽然我不能完全使用该代码,但我会对其进行一些修改,以避免违反规则。教授说这在将来会有帮助,但我真的看不到我自己在做一个项目,而不是我们 正在加载%x。无论如何,再次感谢!
#include <stdio.h>
#include <limits.h>
#include <ctype.h>

#define QUAD  4u    /* if you need a constant, #define one (or more) */
#define QBYTES 8u

/** binary representation of 'v' padded to 'sz' bits.
 *  the padding amount is limited to the number of
 *  bits in 'v'. valid range: 1 - sizeof v * CHAR_BIT.
 */
void binprnpad (const unsigned long v, size_t sz)
{
    if (!sz) { fprintf (stderr, "error: invalid sz.\n"); return; }
    if (!v)  { while (sz--) putchar ('0'); return; }

    if (sz > sizeof v * CHAR_BIT)
        sz = sizeof v * CHAR_BIT;

    while (sz--)
        putchar ((v >> sz & 1) ? '1' : '0');
}

int main (void) {

    unsigned ndx = 0;   /* index of the hex byte read */

    fputs ("enter hex IP: ", stdout);   /* read/validate input */

    while (ndx < QBYTES) {  /* read until 8 hex bytes read */
        unsigned char c = toupper(getchar());   /* read char as upper-case */
        if (isdigit (c)) {                      /* if [0-9] */
            binprnpad (c - '0', QUAD);
            ndx++;
        }
        else if (isxdigit (c)) {                /* if [A-F] */
            binprnpad (c - '7', QUAD);
            ndx++;
        }
        else if (c == '.')                      /* if '.' */
            putchar (c);
        else {      /* handle character not [0-9A-F.] */
            fputs ("(error: invalid character input)\n", stderr);
            break;
        }
    }
    putchar ('\n');     /* tidy up with newline */

    return 0;
}