【问题标题】:store a string in an int将字符串存储在 int 中
【发布时间】:2009-11-22 23:30:48
【问题描述】:

我尝试将字符串存储为整数,如下所示:

我读取字符串的字符,每 4 个字符执行一次:

val = (int) ch << 24 | (int) ch << 16 | (int) ch << 8 | (int) ch;

然后我将整数值放入称为内存 (=&gt; int memory[16]) 的整数数组中。

我想以自动方式对字符串的每个长度执行此操作,而且对于任意大小的字符串,我很难再次反转该过程。有什么帮助吗?

编辑:

(从下方)

基本上,我在 JAVA 中做一个练习。这是一个 MIPS 模拟器系统。我有寄存器、基准、指令、标签、控制、APSImulator 类和其他类。当我尝试将程序从数组加载到模拟器的内存时,我实际上读取了数组中称为“程序”的每个内容并将其放入内存中。内存长 2048 位,宽 32 位。寄存器也被声明为 32 位整数。因此,当数组中有像 Datum.datum("string") 这样的内容时——Datum 类具有 IntDatum 和 StringDatum 子类——我必须以某种方式将“string”存储在模拟器的内存数据段中。内存是 0-1023 文本和 1024-2047 数据区域。我还必须用 null char 分隔字符串 - 加上对完整内存的任何检查等。我发现将字符串存储到 MemContents 的一种方法(引用类型 - 空接口 - 由内存字段所属的类实现)是将字符串每隔(2个或4个符号)存储到寄存器中,然后获取寄存器的内容并将其存储在内存中。所以,我发现实现这一点非常困难,相反的过程也很困难。

【问题讨论】:

  • 你能保证输入的长度总是 4 个字符的整数倍吗?
  • 您使用的是 C 还是 Java?您标记了两种语言。
  • 为什么要将它放在一个整数数组中? char 数组不是更直接吗?
  • 这个问题是关于 C 还是关于 Java(你有两个标签)?在后一种情况下,您应该记住 Java 字符串是 Unicode 而 char 是 16 位
  • 我认为他正在尝试将 32 位整数打包和解包到字节流中。

标签: java types bit-manipulation


【解决方案1】:

如果你在 C 中工作,你的字符串在一个大小为 int 倍数的 char 数组中,你可以将指针指向 char 数组,将其转换为指向 int 数组的指针并执行任何你想要的 int 数组。如果您没有最后一个保证,您可以简单地编写一个函数来动态创建您的 int 数组:

size_t IntArrayFromString(const char * Source, int ** Dest)
{
    size_t stringLength=strlen(Source);
    size_t intArrElements;
    intArrElements=stringLength/sizeof(int);
    if(stringLength%sizeof(int)!=0)
        intArrElements++;
    *Dest=(int *)malloc(intArrElements*sizeof(int));
    (*Dest)[intArrElements-1]=0;
    memcpy(Dest, Source, stringLength);
    return intArrElements;
}

调用者负责释放 Dest 缓冲区。 (我不确定它是否真的有效,我没有测试它)

【讨论】:

    【解决方案2】:

    您是否考虑过简单地使用 String.getBytes() ?然后您可以使用字节数组创建ints(例如,使用BigInteger(byte[]) 构造函数。

    这可能不是最有效的解决方案,但可能不太容易出错并且更具可读性。

    【讨论】:

      【解决方案3】:

      假设 Java:您可以查看 ByteBuffer 类,它是 getInt 方法。它有一个byte order parameter,您需要先配置它。

      【讨论】:

        【解决方案4】:

        基本上,我在 JAVA 中做一个练习。这是一个 MIPS 模拟器系统。我有寄存器、基准、指令、标签、控制、APSImulator 类和其他类。当我尝试将程序从数组加载到模拟器的内存时,我实际上读取了数组中称为“程序”的每个内容并将其放入内存中。内存长 2048 位,宽 32 位。寄存器也被声明为 32 位整数。因此,当数组中有像 Datum.datum("string") 这样的内容时——Datum 类具有 IntDatum 和 StringDatum 子类——我必须以某种方式将“string”存储在模拟器的内存数据段中。内存是 0-1023 文本和 1024-2047 数据区域。我还必须用 null char 分隔字符串 - 加上对完整内存的任何检查等。我发现将字符串存储到 MemContents 的一种方法(引用类型 - 空接口 - 由内存字段所属的类实现)是将字符串每隔(2个或4个符号)存储到寄存器中,然后获取寄存器的内容并将其存储在内存中。所以,我发现实现这一点非常困难,相反的过程也很困难。

        【讨论】:

        • Ponty:改用这个来编辑问题。
        【解决方案5】:

        在 C 中执行此操作的一种常见方法是使用 union。它可能看起来像

        union u_intstr {
          char fourChars[4];
          int  singleInt;
        };
        

        将字符设置为联合

        union u_intstr myIntStr;
        myIntStr.fourChars[0] = ch1;
        myIntStr.fourChars[1] = ch2;
        myIntStr.fourChars[2] = ch3;
        myIntStr.fourChars[3] = ch4;
        

        然后访问 int as

        printf("%d\n", myIntStr.singleInt);
        

        编辑

        在您的情况下,对于 16 个整数,联合可以扩展为看起来像

        union u_my16ints {
          char str[16*sizeof(int)];
          int  ints[16];
        };
        

        【讨论】:

        • 这取决于执行环境的词序,而OP的原始代码没有。
        • @caf 是的,但是这样你可以确定字符像字符串一样排列。
        • @Mark Byers:从一开始就是C。
        【解决方案6】:

        这是我想出来的

        int len = strlen(str);
        int count = (len + sizeof(int))/sizeof(int);
        int *ptr = (int *)calloc(count, sizeof(int));
        memcpy((void *)ptr, (void *)str, count*sizeof(int));
        

        由于使用了 calloc(),结果缓冲区至少有一个 NULL,可能更多来填充最后一个整数。这是不可移植的,因为整数是本机字节顺序的。

        【讨论】:

        • 他想要一个 Java 解决方案,而不是 C。
        猜你喜欢
        • 2014-05-06
        • 1970-01-01
        • 1970-01-01
        • 2015-07-28
        • 1970-01-01
        • 2012-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多