Questo thread mi ha stuzzicato e, per colpa di anycolouryoulike

, mi sono messo sotto ad implementare un programmino per convertire da binario ad ASCII una stringa.
Qui sotto riporto il codice che ne è risultato. Probabilmente conterrà schifezze (sono un po' arrugginito col C), ma a me funziona.
Prendetene spunto tranquillamente:
Codice: Seleziona tutto
/*
bin2dec2ascii
A basic C program to convert a binary number to decimal and ASCII form,
without the use of strtol() like functions.
Made by 414N
*/
# include <stdio.h>
# include <malloc.h>
# include <string.h>
# include <ctype.h>
# include <stdlib.h>
# define MAXLENGTH 100
/*
This function checks that the char* given in input contains only '0' or '1'
Every other character (including newline, so be warned using fgets to read
the string from stdin) makes it fail.
Returns 0 if the given number is a valid binary number, -1 otherwise.
*/
int checkNumber (char *numToCheck);
/*
This function converts the given binary number (as a char sequence) to an unsigned decimal.
It ignores the sign.
*/
long convertToDec (char *numToConvert);
/*
This function converts the given binary number (as a char sequence) to a signed decimal.
*/
long convertToDecSign (char *numToConvert);
/*
This function returns the two's-complement of the binary number given in input.
This procedure is needed whenever you encounter a negative binary number (the
Most Significative Bit is set to '1') and you want to know its absolute value.
*/
char* c2 (char *number);
/*
This function returns the ASCII representation of the given binary string.
*/
char* convertToASCII (char *numToConvert);
/*
This function returns the byte index in input. The index starts at 1.
*/
char *getByte (int byteNum, char* string);
/*
This function adds '0's to the number given in order to align to a
multiple of 8
*/
void adjustBits (char *bits);
int main (int argc, char *argv[])
{
// The pointer to the binary number to be read from stdin.
char *binNumber = malloc ( (sizeof *binNumber) * MAXLENGTH );
if (binNumber == NULL){
fprintf (stderr, "First memory allocation failed. Exiting.\n");
return 1;
}
// Read the number from stdin
fprintf (stdout, "\nPlease enter the binary number.\n");
fscanf (stdin, "%100s", binNumber);
fprintf (stdout, "\nOk, you entered %s.", binNumber);
// Checking that the number consists only of '0' and '1'.
if (checkNumber(binNumber) != 0){
fprintf (stderr, "\nYou entered an invalid binary number.\n");
return 2;
}
fprintf (stdout, "\nDecimal conversion\n");
fprintf (stdout, "\nWithout sign:\n\t%sb = %li\n", binNumber, convertToDec (binNumber));
fprintf (stdout, "\nWith sign:\n\t%sb = %li\n", binNumber, convertToDecSign (binNumber));
fprintf (stdout, "\nASCII conversion\n");
adjustBits (binNumber);
fprintf (stdout, "\n%s : %s\n", binNumber, convertToASCII(binNumber));
free (binNumber);
return 0;
}
int checkNumber (char *numToCheck)
{
int i;
for (i = 0; i < strlen (numToCheck); i++){
if (numToCheck[i] != '0' && numToCheck[i] != '1')
return -1;
}
return 0;
}
long convertToDec (char *numToConvert)
{
int i;
long num = 0;
long exp = 1;
for (i = strlen(numToConvert) - 1; i >= 0; i--){
if (numToConvert[i] == '1')
num += exp;
exp *= 2;
}
return num;
}
long convertToDecSign (char *numToConvert)
{
if (numToConvert[0] == '1'){
// The number is negative.
char *numC2 = c2 (numToConvert);
return -1 * convertToDec(numC2);
}else
return convertToDec (numToConvert);
}
char* c2 (char *number)
{
char *cNumber = NULL;
int i = 0;
int carry = 0;
cNumber = malloc ( (sizeof *cNumber) * (strlen (number) + 1) );
if (cNumber == NULL){
fprintf (stderr, "\nMemory allocation error. Exiting.\n");
exit (3);
}
for (i = 0; i <= strlen(number); i++)
switch (number[i])
{
case '0':
cNumber[i] = '1';
break;
case '1':
cNumber[i] = '0';
break;
default:
cNumber[i] = number[i];
}
for (i = strlen (cNumber) - 1, carry = 1; i >= 0; i--)
switch (cNumber[i])
{
case '0':
if (carry == 1){
cNumber[i] = '1';
carry = 0;
}
break;
case '1':
if (carry == 1)
cNumber[i] = '0';
}
return cNumber;
}
char* convertToASCII (char *numToConvert)
{
char *string = NULL;
char *byte = NULL;
int bytes = 0;
int i = 0;
// long number = 0;
char character = '0';
// First off, we align the bits to be a multiple of 8.
adjustBits (numToConvert);
// Next, we allocate the space to host the ASCII representation
// of the binary number.
bytes = strlen (numToConvert)/8;
string = malloc ((sizeof *string) * bytes + 1);
if (string == NULL){
fprintf (stderr, "\nMemory allocation error. Exiting\n");
exit (4);
}
// Now, for each byte contained inside the string, we
// get its ASCII representation.
for (i = 0; i < bytes; i++){
byte = getByte (i + 1, numToConvert);
if (strcmp (byte, "Error") == 0){
fprintf (stderr, "\nError getting byte number %d out of %s", i + 1, numToConvert);
exit (6);
}
character = (char) convertToDec (byte);
// if (isgraph (character))
string[i] = character;
}
string [i] = '\0';
return string;
}
char* getByte (int byteNum, char* string)
{
char *byte = NULL;
int index1 = 0;
int index2 = 0;
int i = 0;
int j = 0;
if (byteNum > strlen (string) || byteNum <= 0)
return "Error";
index1 = (byteNum - 1) * 8;
index2 = index1 + 7;
byte = malloc ( (sizeof *byte) * 9 );
if (byte == NULL){
fprintf (stderr, "\nMemory allocation error. Exiting\n");
exit (5);
}
for (i = index1, j = 0; i <= index2 || i < strlen (string); i++, j++)
byte[j] = string [i];
if (i != index2)
byte[8] = '\0';
return byte;
}
void adjustBits (char *bits)
{
char *zeroes = NULL;
char *newString = NULL;
int i = 0;
if (strlen (bits) % 8 != 0){
// We need to fill the rest with '0's.
int zerosToAdd = 8 - strlen(bits) % 8;
zeroes = malloc ( (sizeof *zeroes) * zerosToAdd + 1);
if (zeroes == NULL){
fprintf (stderr, "\nMemory allocation error (zeroes). Exiting\n");
exit (6);
}
for (i = 0; i < zerosToAdd; i++)
zeroes[i] = '0';
zeroes[zerosToAdd] = '\0';
newString = malloc ( (sizeof *newString) * ( strlen(bits) + zerosToAdd) + 1);
if (newString == NULL){
fprintf (stderr, "\nMemory allocation error (newString). Exiting\n");
exit (7);
}
strcpy (newString, zeroes);
free (zeroes);
strcat (newString, bits);
strcpy (bits, newString);
}
}
Una compilata con
e vai col lissio
