Reputation: 45
I am writing a program that converts user input to either ASCII values or binary values. If the string contains letters, each letter should be converted to ASCII. Strings of numbers will be converted to binary value of entire string. If both letters and numbers are entered, each letter will be converted to ASCII and the numbers can/will only be separated by letters, for example "32" will print the binary value "00100000", but "3a2" should be converted to "00000011", "97", "00000010".
The way the program is currently written, strings of numbers convert to binary perfectly. However, strings of letters add a decimal "0" to the end. The output converts each letter to its ASCII value, then converts the "0" to binary. I am unsure as to where this "0" is coming from. Additionally, strings beginning and ending with digits (for example "6j3") will print the ASCII value of j, then the binary value of "6", skipping the "3" entirely and printing the "j" before the "6". I would like to print each ASCII/binary value in the exact order of the user input.
I am posting my entire code for any necessary clarification, but I believe the issue is in the determineChars() function. I am also looking to use the char* letters and char* numbers functions to efficiently handle the appropriate data and store the final num[] and let[] arrays, but I am unsure of how to do this.
I am quite a beginner to C, so excuse the messiness. Corrections, as well as any further optimizations would be greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#define EIGHT_BITS 255
#define SIXTEEN_BITS 65535
#define THIRTY_TWO_BITS 4294967295UL
#define SIXTY_FOUR_BITS 18446744073709551615ULL
// defined in case of booleans
typedef enum { false, true } bool;
// GET # OF ELEMENTS IN STRING
size_t getSize(char* input) {
size_t size;
size = strlen(input);
printf("Number of Characters..... %d", size);
//printf("\n----------------------------------");
return size;
}
// DETERMINE NUMBER OF BITS TO OUTPUT
int getBitLength(unsigned long long d) {
int l;
if (d <= EIGHT_BITS) {
l = 8;
}
else if (d > EIGHT_BITS && d <= SIXTEEN_BITS) {
l = 16;
}
else if (d > SIXTEEN_BITS && d <= THIRTY_TWO_BITS) {
l = 32;
}
else if (d > THIRTY_TWO_BITS && d <= SIXTY_FOUR_BITS) {
l = 64;
}
printf("\nBits..................... %d", l);
return l;
}
// CONVERT INPUT TO BINARY VALUE
void convertToBinary(char* input) {
static int b[64];
int i, j, length, r;
unsigned long long decimal;
char* pEnd;
// converts input to ull
decimal = strtoull(input, &pEnd, 0);
printf("\n\n---------------- %I64u ------------------", decimal);
printf("\nULL...................... %I64u", decimal);
length = getBitLength(decimal);
// creates array
for (i = 0; i < length; i++) {
r = decimal % 2;
decimal /= 2;
b[i] = r;
}
// reverses array for binary value
printf("\nBinary Value............. ");
for (j = length - 1; j >= 0; j--) {
printf("%d", b[j]);
}
}
char* numbers(char* input) {
char* num = (char*) malloc(sizeof(char) * 25);
return num;
}
char* letters(char* input) {
char* let = (char*) malloc(sizeof(char) * 25);
return let;
}
void determineChars(char* input) {
int i;
char* num = numbers(input);
char* let = letters(input);
size_t inputSize = getSize(input);
// FOR EACH CHARACTER IN INPUT
for (i = 0; i < inputSize; i++) {
if (isdigit(input[i])) {
// stores number values from input into separate array
num[i] = input[i];
printf("\nNumbers: %c", num[i]);
}
if (!isdigit(input[i])) {
// stores letter values from input into separate array
let[i] = input[i];
printf("\nLetters: %c", let[i]);
// prints separator line + ASCII value
printf("\n\n---------------- %c ------------------", let[i]);
printf("\nASCII Value of %c......... %d", let[i], let[i]);
// removes char from input array
input[i] = ' ';
}
}
// char array must consist of digits only
convertToBinary(num);
}
int main() {
// GET INPUT
char input[50];
scanf("%s", input);
determineChars(input);
return 0;
}
Upvotes: 0
Views: 118
Reputation: 26800
I would like to print each ASCII/binary value in the exact order of the user input.
In that case, you would have to restructure your code a bit. This is because if the input contains only digits you will have to print binary and alternate being chars and digits if the string contains both. I have tried to do this with the following code, cleaned it up a bit, removed the warnings and memory leaks.
See if this is what you want:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#define EIGHT_BITS 255
#define SIXTEEN_BITS 65535
#define THIRTY_TWO_BITS 4294967295UL
#define SIXTY_FOUR_BITS 18446744073709551615ULL
// GET # OF ELEMENTS IN STRING
size_t getSize(char* input) {
size_t size;
size = strlen(input);
printf("Number of Characters..... %d\n", size);
//printf("\n----------------------------------");
return size;
}
// DETERMINE NUMBER OF BITS TO OUTPUT
int getBitLength(unsigned long long d) {
int l;
if (d <= EIGHT_BITS) {
l = 8;
}
else if (d > EIGHT_BITS && d <= SIXTEEN_BITS) {
l = 16;
}
else if (d > SIXTEEN_BITS && d <= THIRTY_TWO_BITS) {
l = 32;
}
else if (d > THIRTY_TWO_BITS && d <= SIXTY_FOUR_BITS) {
l = 64;
}
printf("\nBits..................... %d", l);
return l;
}
// CONVERT INPUT TO BINARY VALUE
void convertToBinary(char* input) {
static int b[64];
int i, j, length, r;
unsigned long long decimal;
char* pEnd;
// converts input to ull
decimal = strtoull(input, &pEnd, 0);
printf("\n---------------- %I64u ------------------", decimal);
printf("\nULL...................... %I64u", decimal);
length = getBitLength(decimal);
// creates array
for (i = 0; i < length; i++) {
r = decimal % 2;
decimal /= 2;
b[i] = r;
}
// reverses array for binary value
printf("\nBinary Value............. ");
for (j = length - 1; j >= 0; j--) {
printf("%d", b[j]);
}
printf("\n");
}
void determineChars(char* input) {
int i;
long ret;
char* ptr;
char c;
size_t inputSize = getSize(input);
ret = strtol(input, &ptr, 10);
if((ret == 0) || ((strlen(ptr) != 0) && (strlen(input) != strlen(ptr))))
{
for (i = 0; i < inputSize; i++) {
if (isdigit(input[i])) {
c = input[i];
printf("\nNumber: %c", c);
convertToBinary(&c);
}
if (!isdigit(input[i])) {
// stores letter values from input into separate array
printf("\nLetter: %c", input[i]);
// prints separator line + ASCII value
printf("\n---------------- %c ------------------\n", input[i]);
printf("ASCII Value of %c......... %d\n", input[i], input[i]);
// removes char from input array
}
}
}
else
convertToBinary(input);
}
int main() {
// GET INPUT
char input[50];
scanf("%s", input);
determineChars(input);
}
I also tried out the test cases you mentioned in the question along with few others and it seems to work fine.
32
Number of Characters..... 2
---------------- 32 ------------------
ULL...................... 32
Bits..................... 8
Binary Value............. 00100000
3a2
Number of Characters..... 3
Number: 3
---------------- 3 ------------------
ULL...................... 3
Bits..................... 8
Binary Value............. 00000011
Letter: a
---------------- a ------------------
ASCII Value of a......... 97
Number: 2
---------------- 2 ------------------
ULL...................... 2
Bits..................... 8
Binary Value............. 00000010
6j3
Number of Characters..... 3
Number: 6
---------------- 6 ------------------
ULL...................... 6
Bits..................... 8
Binary Value............. 00000110
Letter: j
---------------- j ------------------
ASCII Value of j......... 106
Number: 3
---------------- 3 ------------------
ULL...................... 3
Bits..................... 8
Binary Value............. 00000011
Upvotes: 1