converting string to hex, decimal, and octal

Viewed 506

I am new to learning C and I need to convert a string of characters to integer, hex, octal.

I am aware that I can use char *var_name to point to the base of the string but I do not know how to convert every character in the string to hex, octal, or decimal.

For example:

"my name is stackoverflow"

The program should convert the ASCII values of the string to hex, octal and decimal.

I tried to use atoi but I cant get it to work.

I also tried type casting I could not get that to work either. I thought about sprintf but don't understand how to use it.

The user should be able to enter an arbitrary length string, it only should only end when there is a newline character.

How would I do this?

int main(){
    char *string;
    printf("Enter string: ");
    scanf("%s", string);
    int d = (int) string;
    printf("%d\n",d);
    return 0;
}

Input:

stackoverflow

Output:

-535030240
1 Answers

Regarding the conversion issue, no conversion is needed, the string characters have its encoding already defined, you just need to be able to print them correctly in the different bases, and for that printf already provides the specifiers you need:

#include <string.h>

//...

for(size_t i = 0; i < strlen(string); i++){ //printing hex codes
    printf("%3x ", string[i]);
}
putchar('\n');
for(size_t i = 0; i < strlen(string); i++){ //printing decimal codes
    printf("%3d ", string[i]);
}
putchar('\n');
for(size_t i = 0; i < strlen(string); i++){ //printing octal codes
    printf("%3o ", string[i]);
}

As for your code, there are some problems:

scanf("%s", string);

string is an uninitialized pointer, it does not have any memory reserved for it, trying to store anything in it leads to undefined behavior, you need to allocate memory for it or otherwise make it point to a valid, writable memory location.

e.g:

char *string = calloc(2048, sizeof *string); //space for 2047 characters + null byte

Furthermore, scanf using %s specifier will stop reading when it finds a space so if you input my name is stackoverflow, only my will be parsed. It's also very insecure as it can easily overflow the destination buffer, my advise is for you to use fgets(an example is provided ahead).

After that when you use:

 int d = (int) string;

In your code, because string is uninitialized, the behavior is still undefined.

If you initialize it like in the example above, what happens is that you are converting the address of the memory where string is pointing to, to an int.

This is still problematic as an address, in today's 64 bit machines, is usually 8 bytes in size whereas an int is usually 4 bytes, so you'll likely have a loss of data in the conversion.

When you print it what you are printing is the truncated memory address pointed by the string pointer.

Needless to say that the code does not do what you want it to do, and using atoi or something similar won't work either because these functions only convert digits, when they try to parse a non-digit they fail, but as I said, no conversion is needed.


As for the parsing of indeterminate number of characters, I think it's unnecessary, and has too much overhead because you'll need to reallocate memory as the string grows. Giving it a large size should do the trick.

However if you really want to do it like that you could use the following strategy:

Online demo

#include <stdio.h>
#include <stdlib.h>

#define MIN_SIZE 50 //size above 50, memory will be reallocated

int main(){

    char *string = calloc(MIN_SIZE, sizeof *string);

    if(string == NULL){
        return EXIT_FAILURE;
    }

    int ind = 0; //string index

    if(string == NULL){
        return EXIT_FAILURE;
    }
    while((string[ind] = getchar()) != '\n'){ //parse till '\n'
        //removing '\n' or EOF
        if(string[ind] == EOF || string[ind] == '\n'){
            string[ind] = '\0';
            break;
        }
        ind++;
        if(ind >= MIN_SIZE){ //if size is more than 50, reallocate
           string = realloc(string, ind + 1);
           if(string == NULL){
               return EXIT_FAILURE;
           }
        }
    }
    //...
}

In the bellow example, which is what I would use, we have a 2047 character string, wich is quite large and only uses 2Kb of memory wich is very litle by today's standards, this is the limit size of the string, above that the characters will not be parsed:

Online demo

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

#define SIZE 2048

//...

char *string = calloc(SIZE, sizeof *string); 

if(string == NULL){
    return EXIT_FAILURE;
}

fgets(string, SIZE, stdin); //parse with fgets
string[strcspn(string, "\n")] = '\0'; //removing '\n'

Sample input:

my name is stackoverflow

Output:

 6d  79  20  6e  61  6d  65  20  69  73  20  73  74  61  63  6b  6f  76  65 
109 121  32 110  97 109 101  32 105 115  32 115 116  97  99 107 111 118 101 
155 171  40 156 141 155 145  40 151 163  40 163 164 141 143 153 157 166 145
Related