Log in

View Full Version : string CHAR in C?


Episodio1
29th October 2007, 19:35
I'm using "decimal 2 binary" conversor in the MAIN () and everything goes well: the result is 8bit long char ALWAYS (if the result binary is "101" I get "00000101").

But when I use exactly the same code in a function the program freezes or doesn't work as I wished.

I have initialized a char aux[8]="0000000" inside the function.

The same if I initialize a char aux[8]="0000000" as a global variable.

The same if I use strcpy(aux,"0000000"). With this one I get diferent results if I change the line of position in every compile!!! WTFF!!!!

And I get even diferent results if I compile in windows or linux. O_o

The result I get closest to my desire is: if the binary is 101, I get "101" (length="3") ).

Does anyone know if I wrote the function in bitlevel I'd get always a 8 bit long CHAR ???? If yes, is there any public code available for a "decimal 2 binary (char)" conversion?

Thanks.

my current function:



void dec2bin(int dec, char *binary)
{
int i,resto,aux,k=0;
char binaux[8]="00000000";

i=0;
aux=dec;
while (aux>0)
{
resto=aux%2; /* remain */
aux=aux/2;
binaux[i]=(resto + '0'); /* DECIMAL to CHAR */
i=i+1;
}

while (i>=0) /* return BINAUX inverted */
{
binary[k]=binaux[i-1];
i=i-1;
k=k+1;
}

}

fccHandler
29th October 2007, 20:34
Two things...

The string "00000000" is actually 9 chars, because C adds a hidden zero byte to terminate the string. So you need to initialize binaux as a 9 char string, or just leave [] empty:

char binaux[] = "00000000";

The other problem I see is the second loop references binaux[i-1], yet it also allows i to be zero. If i is zero, then your reference is out of bounds, and the result is unpredictable.

Episodio1
29th October 2007, 22:31
Thank you FCCHandler but I had already tried to code with the "\0" in mind. Same results... :(

Every time I filled BINAUX with ZEROs it didn't work (or it worked sometimes).But, I dont know why.... after reading your post I realized that I could try, as last resort, to add ZERO's BEFORE the inversion.

And it works!! Huh?? (at least for the time being) ;)


for (i=strlen(binaux);i<8;i=i+1)
{
binaux[i]='0';
}
while (i>=0) /* return BINAUX inverted */
{
binary[k]=binaux[i-1];
i=i-1;
k=k+1;
}

fccHandler
29th October 2007, 22:57
for (i=strlen(binaux);i<8;i=i+1)

That makes no sense at all. strlen(binaux) is 8, so the for loop shouldn't even execute... :confused:

You're making this far more complicated than it needs to be. Step back a moment and rethink the task. You want to check the 8 bits of "dec" one at a time, and set the corresponding 8 bytes of "binary" to match them. You can read the bits of "dec" (and write the bytes of "binary") either forwards or backwards, think about that. And you can do the task in one loop, without "binaux" and all that reshuffling.

Guest
29th October 2007, 22:58
Your code is still incorrect. Here is a simple and correct version:

#include <stdio.h>
#include <string.h>

void dec2bin(int x, char *result)
{
int i;

result[0] = 0;
for (i = 7; i >= 0; i--)
strcat(result, x & (1 << i) ? "1": "0");
}

int main(int argc, char *argv[])
{
char result[9];

dec2bin(54, result);
printf("Decimal %d is binary %s\n", 54, result);
return 0;
}

fccHandler
29th October 2007, 23:13
neuron2 to the rescue.

I wasn't going to let him off that easily. I wanted him to fix it himself. :p

Episodio1
30th October 2007, 00:15
"That makes no sense at all. strlen(binaux) is 8."

That's the weird thing!!! Even if I set the length to 8, the function changes it somehow! So I get diferent lenghts everytime.

It seems that strlen(binaux) in that example is the lenght of the binary result as in: "101" >> length=3.

So I have to add '0' at the end with that FOR. :( :(

"You want to check the 8 bits of "dec" one at a time"

No! DEC is an INTEGER.

"Step back a moment and rethink the task."

I've really done that. Believe me, the LENGTH changed everytime. :(
Try that code (using the function, not pasting the code in MAIN() ), and tell me what length you get with a few examples.


Excellent, neuron, thank you for that. But... 'incorrect'???

fccHandler
30th October 2007, 01:01
OK, I tried your code, and now I think I understand what the problem is, and I misstated your task. You want to take an int, and write it to a variable length string, but with the leading zero bits omitted.

The problem is the last loop, while (i >= 0). As I explained before, if i is zero, then you're reading the final byte from an unknown location in memory. When I tested it, that byte just happened to be zero, so the result was correct. But after compiling you have no way to know what will be there.

The fix is to remove the "for" loop, and change the second loop to this:

while (i>0) /* return BINAUX inverted */
{
binary[k]=binaux[i-1];
i=i-1;
k=k+1;
}

binary[k]=0; /* string terminator */


Note that if you really intend to print a full int, you'll need binaux to be 32 chars.

Episodio1
30th October 2007, 02:08
"but with the leading zero bits omitted."

No, I want with the leading zeros.

Thanks for the "i>0" :)


"if you really intend to print a full int, you'll need binaux to be 32 chars."

Yes. The input will be always [-127,128] >> 8 bits
I'm implementing an 8-bit ALU and I have to check individual bits from time to time, that's why I must get "00000101" intead of "101". :)

Guest
30th October 2007, 03:33
Excellent, neuron, thank you for that. But... 'incorrect'??? Yes! For example, you have this line of code:

char binaux[8]="00000000";

But that string won't fit in the array as you have declared it (as fccHandler already explained). That's just the first error.

I'm implementing an 8-bit ALU and I have to check individual bits from time to time, that's why I must get "00000101" intead of "101". Aren't you aware that you don't have to convert the INT to a string to test its individual bits? If the bits are numbered 0 to 7 (as is usual) then you can test bit N like this:

if (x & (1 << N))
// bit N is a 1
else
// bit N is a 0

You need some remedial work in C programming.

fccHandler
30th October 2007, 03:59
No, I want with the leading zeros.
Well, then the first loop isn't doing what you want, because it exits the loop as soon as there are no more "1" bits (counting from LSB to MSB).

Yes. The input will be always [-127,128] >> 8 bits
But when I said, "You want to check the 8 bits of dec", you contradicted me! If you are treating dec as an 8-bit number, change the first loop to say "while (i<8)."

Or better yet, just use neuron2's code. ;)

Episodio1
30th October 2007, 16:07
Ok, I'll learn how to work with bit level in C, as neuron2's code does. :)

Thanks, both.


"you don't have to convert the INT to a string"

An ALU works with binary words. I can't code the operations inside the ALU with INT. The point is not that the software actually works, but if I understan the inner workings of an ALU as well.

It's not accepted that I write "out=data1+data2".

Guest
30th October 2007, 16:51
An ALU uses registers. A register is an array of binary bits. You can store an integer in a register. It has bits. E.g., the integer 5 will look like this is the register:

00000101

It certainly is not represented as a string in your ALU!

Are you trying to simulate an ALU in software and so are using a string to represent your register? That seems silly to me, when you can use an unsigned char for an 8-bit register.

Episodio1
30th October 2007, 19:33
"you can use an unsigned char for an 8-bit register"

The problem is that I don't know how to work in a bit level in C. How do I store "11110000" in a UNSIGNED CHAR?
If I store "r" (for example) in my UNSIGNED CHAR I dont know how to work with it. How do I apply a LOGICAL NOT on it?

So that's why I have to work bit by bit in an 8-char string. :(
* Logical NOT:
If (register[i]=='1' )
>> register[i]='0';
else
>> register[i]='1';

fccHandler
30th October 2007, 20:36
It sounds to me like you're diving head first into coding in a language you're not familiar with. You need to do some more studying of the C programming language, because this is really beginner's stuff you're asking, and I doubt the people here are going to take the time to walk you through it. Anyway good luck with your ALU, I hope it works out for you.

Guest
30th October 2007, 20:43
"you can use an unsigned char for an 8-bit register"

The problem is that I don't know how to work in a bit level in C. How do I store "11110000" in a UNSIGNED CHAR?
If I store "r" (for example) in my UNSIGNED CHAR I dont know how to work with it. How do I apply a LOGICAL NOT on it?
Bit operations are simple in C. This kind of application is exactly what they were designed for. Using strings is an abomination.

How to store 11110000 in an unsigned char? Here are some ways:

unsigned char reg;

1) reg = 0xf0;

2) reg = 240;

3) reg = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4);

And here's a bitwise inverter like your example:

if (reg & (1 << i));
reg &= ~(1 << i);
else
reg |= (1 << i);

or do the same without having to test the bit:

reg ^= (1 << i);

Get a good C book and read the chapter on bit operators.

Inventive Software
31st October 2007, 14:31
Using strings is an abomination.

I just had a lecture explaining how using strings in C++ is much easier than using CHAR. I also got a crash course in sets too. I understand this is C, but still.... ;)

Guest
31st October 2007, 14:32
I just had a lecture explaining how using strings in C++ is much easier than using CHAR. Easier for what? For bit manipulation? That's ridiculous, and if the instructor is saying that he's an idiot. Or maybe he meant that it's easier for idiots who are too stupid to use bit operators.

Inventive Software
31st October 2007, 18:22
He said nothing about bit manipulation, which is where chars come in more useful. It was to do with comparisons, mostly.

Guest
31st October 2007, 19:18
Then why did you bring it up, since we're talking about bit manipulation?

And what kind of comparisons are you talking about?

dancho
31st October 2007, 20:33
Bitwise Operations in C: (http://www.gamedev.net/reference/articles/article1563.asp)

Inventive Software
31st October 2007, 21:02
@neuron2: I brought it up cause I'm a dimwit and didn't get the topic in question fully, and you made a point which I countered rather badly with. Apologies. I'll just hide in a corner next time and cry "C++"! ;)

Rainy
31st October 2007, 23:28
The input will be always [-127,128] >> 8 bits


Eight bit can hold a range from -128 to +127 using two's complement and -127 to +127 using excess-127 and one's complement whereat 0 has two representations. You should decide which one you're using.

Episodio1
1st November 2007, 00:17
Yeah, rainy, you're right. Anyways, I said the first number that came to my mind with 8 bits. Actually I have to work with [0-255] and then use and added SIGN BIT as ALU's flag. :)

My point wasn't "how to code properly in C", but "why string char behaviour changes if I move the code from MAIN to a function". :)

Rainy
1st November 2007, 00:45
Would you mind showing us how you actually call your function?

Guest
1st November 2007, 00:45
My point wasn't "how to code properly in C", but "why string char behaviour changes if I move the code from MAIN to a function". :) Because your code is brain-dead, and brain-dead code acts unpredictably. Any other questions?

Episodio1
1st November 2007, 01:13
Nop. I got it from first time. ^_^