views:

377

answers:

7

Hi, i try to store a string into an integer as follows:

i read the characters of the string and every 4 characters i do this:

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

Then i put the integer value in an array of integer that is called memory ( => int memory[16]).

I would like to do it in an automatic way for every length of a string, plus i have difficulties to inverse the procedure again for an arbitrary size string. Any help?

EDIT:

(from below)

Basically, i do an exercise in JAVA. It's a MIPS simulator system. I have Register, Datum, Instruction, Label, Control, APSImulator classes and others. When i try to load the program from an array to simulator's memory, i actually read every contents of the array which is called 'program' and put it in memory. Memory is 2048 long and 32 bits wide. Registers are declared also 32bit integers. So when there is an content in the array like Datum.datum( "string" ) - Datum class has IntDatum and StringDatum subclasses - i have somehow to store the "string" in the simulator's data segment of memory. Memory is 0-1023 text and 1024-2047 data region. I also have to delimit the string with a null char - plus any checkings for full memory etc. I figure out that one way to store a String to MemContents ( reference type - empty interface - implemented by class that memory field belongs to ) is to store the string every ( 2 or maybe 4 symbols ) to a register and then take the contents of the register and store it in memory. So, i found very difficult to implement that and the reverse procedure also.

A: 

Assuming Java: You could look at the ByteBuffer class, and it's getInt method. It has a byte order parameter which you need to configure first.

Mark Byers
A: 

One common way to do this in C is to use a union. It could look like

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

Set the chars into the union as

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

and then access the int as

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

Edit

In your case for 16 ints the union could be extended to look like

union u_my16ints {
  char str[16*sizeof(int)];
  int  ints[16];
};
epatel
This depends on the word ordering of the execution environment, whereas the OP's original code did not.
caf
@caf True, but this way you are sure the chars is layed out like a string.
epatel
It's Java, not C.
Mark Byers
@Mark Byers: It said C from the beginning.
epatel
+1  A: 

If you are working in C, you have your string in a char array that is of a size multiple of a int, you can just take the pointer to the char array, cast it to a pointer to a int array and do whatever you want with your int array. If you don't have this last guarantee, you may simply write a function that creates your int array on the fly:

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

The caller is responsible for freeing the Dest buffer. (I'm not sure if it really works, I didn't test it)

Matteo Italia
A: 

This is what I come up with

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

Due to the use of calloc(), the resulting buffer has at least one NULL, maybe more to pad the last integer. This is not portable because the integers are in native byte order.

ZZ Coder
He wants a solution in Java, not C.
Mark Byers
A: 

Really everything is an array of bytes, the thing you need to make sure of is that when you are using it as an int array is that its size is a multiple of sizeof(int).

This code is two functions that should convert between the two for you. Make sure to free the memory it allocates.

#include <stdlib.h>
#include <string.h>

void charToInt( const char* pChar, int** pDest )
{
    int len = strlen( pChar ) + 1; // for null terminating
    // work out the length the int buf has to be
    int intBufLen = ( len / sizeof( int ) ) + ( len % sizeof( int ) != 0 ? 1 : 0 ); 
    *pDest = (int*)malloc( intBufLen * sizeof( int ) );
    (*pDest)[ intBufLen - 1 ] = 0;
    memcpy( *pDest, pChar, len );
}

void intToChar( const int* pInt, char** pDest )
{
    int len = strlen( (char*)pInt ) + 1;
    *pDest = (char*)malloc( len );
    memcpy( *pDest, (const char*)pInt, len );
}

int main()
{
    const char* charBuf = "omgBBQ6";
    int* intBuff=0;
    char* newChar=0;

    charToInt( charBuf, &intBuff );
    intToChar( intBuff, &newChar );

    free( intBuff );
    free( newChar );
    return 0;
}
0xC0DEFACE
The question said C code initially...
0xC0DEFACE
A: 

Basically, i do an exercise in JAVA. It's a MIPS simulator system. I have Register, Datum, Instruction, Label, Control, APSImulator classes and others. When i try to load the program from an array to simulator's memory, i actually read every contents of the array which is called 'program' and put it in memory. Memory is 2048 long and 32 bits wide. Registers are declared also 32bit integers. So when there is an content in the array like Datum.datum( "string" ) - Datum class has IntDatum and StringDatum subclasses - i have somehow to store the "string" in the simulator's data segment of memory. Memory is 0-1023 text and 1024-2047 data region. I also have to delimit the string with a null char - plus any checkings for full memory etc. I figure out that one way to store a String to MemContents ( reference type - empty interface - implemented by class that memory field belongs to ) is to store the string every ( 2 or maybe 4 symbols ) to a register and then take the contents of the register and store it in memory. So, i found very difficult to implement that and the reverse procedure also.

Ponty
Ponty: Edit the question with this instead.
Spoike
+1  A: 

Have you considered simply using String.getBytes() ? You can then use the byte array to create the ints (for example, using the BigInteger(byte[]) constructor.

This may not be the most efficient solution, but is probably less prone to errors and more readable.

abyx