sprintf to reverse an int and store as char - c

I"m trying to store int array as a str and display it but in the reverse order.
Its only while printing the str that i get junk.
What is wrong in my code?
int main() {
int a[] = { 1, 2, 3 }; // Output should be 321 (char)
int size = sizeof(a) / sizeof(int);
char str[size + 1];
int i;
for (size = size - 1; size >= 0; size--) {
sprintf(&str[size], "%d", a[size]);
//printf("%c\n", str[size]);
}
printf("%s\n", str); // I get garbage.
}

I modified your solution with several bug fixes. For starters, you can't assume that your integer array will only hold single digit values.
And that for loop as you have it:
for(size=size-1;size >= 0;size--)
Is very suspicious looking. (the index variable is the thing its based off?)
Simple solution
This is likely what you meant:
for(i = 0; i < size; i++) {
sprintf(&str[i],"%d", a[size-1-i]);
}
str[size] = '\0';
Or this:
str[size] = '\0';
for(i = size-1; i <= 0; i--) {
sprintf(&str[i],"%d", a[size-1-i]);
}
Better solution
I'm not sure what you are expecting to do if an integer within the a array is negative. So the - sign will just get inserted into str inplace.
The solution I have will first count how many chars are needed for each integer in a. Then it will allocate the str buffer with that length (+1 for null char).
Then we make use of the return value from sprintf to figure out where to concatenate onto. We could use strcat, but this is likely faster.
int main() {
int j = 0;
int a[] = { 1,2,3 }; // Output should be 321 (char)
int size = sizeof(a) / sizeof(int);
int length = 1; // +1 for final null char
// Count the size of characters needed for each integer
// Do a dummy sprintf and use its return value to figure out how many chars are needed
for (int i = 0; i < size; i++) {
char tmp[sizeof(int) * 5]; // sizeof(int)*5 is big enough to hold any integer including a negative value
length += sprintf(tmp, "%d", a[i]); // utilize the return value from sprintf and add it to the running length
}
char str[length];
str[0] = '\0'; // initially null terminate our string
// reverse print chars from a into str
for (int i = 0; i < size; i++) { // use i as index variable, not size
j += sprintf(str + j, "%d", a[size - 1 - i]);
}
printf("%s\n", str);
}

Alternative solution, closer to original posts, and clearly not trying to address the general problem (assume values are single digit):
int a[]={1,2,3}; // Output should be 321 (char)
int size = sizeof(a)/sizeof(int);
char str[size+1];
for(int i=0; i<size ; i++) {
str[size-1-i] = ‘0’ + a[i];
}
str[size] = 0;
printf("%s\n", str); // I get garbage.
}
Taking advantage of the assumed input value, converting each int to character representation at the reverse position.

Related

Why C dosen't split correctly arrays?

I have an array of 64 characters, which I need to divide into two parts, the left part of 32 characters and the right part, also 32 characters.
char *IP_M; // 64 characters array
char L[32]; // left part
char R[32]; // right part
The IP_M array is filled in as follow:
char *start_inital_permutation(const char *input) {
char *output = malloc(64 * sizeof(char));
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
output[i * 8 + j] = input[IP[i][j] - 1];
}
}
return output;
}
...
IP_M = start_inital_permutation(M);
where M is also a 64 characters string. With the following method I tried to fill the other two array (L, R) by spliting the IP_M.
void fill_LR() {
for (int i = 0; i < 32; i++) {
L[i] = IP_M[i];
R[i] = IP_M[i + 32];
}
}
but when I run the following instructions:
printf("IP_M: %s\n", IP_M);
printf("L: %s\n", L);
printf("R: %s\n", R);
the output is:
IP_M: 1100110000000000110011001111111111110000101010101111000010101010
L: 1100110000000000110011001111111111110000101010101111000010101010
R: 11110000101010101111000010101010
I can't get out of this situation, can someone help me please?
*EDIT: also tried the memcpy() method but it still not work!
Here is the Project if someone want to see it:
https://github.com/ionutbogdandonici/DES_C.git
Strings in C are \0 terminated. So the print function will print the string until it reaches the \0 character.
Assign space for null:
char L[33]; // left part
char R[33]; // right part
Add null terminator:
void fill_LR() {
for (int i = 0; i < 32; i++) {
L[i] = IP_M[i];
R[i] = IP_M[i + 32];
}
L[32] = 0;
R[32] = 0;
}
output[i * 8 + j] = input[IP[i][j] - 1]; is gibberish.
Strings in C are null terminated but you never allocate space for a null terminator anywhere, nor do you null terminate your strings.
Don't use global variables.
I was able to salvage your program like this:
#include <stdio.h>
#include <stdlib.h>
char *start_inital_permutation(const char *input) {
size_t count=0;
char *output = malloc(64 * sizeof(char) + 1);
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
output[i * 8 + j] = input[count++];
}
}
output[64] = '\0';
return output;
}
int main()
{
const char input[] = "1100110000000000110011001111111111110000101010101111000010101010";
char *IP_M = start_inital_permutation(input);
char L[32+1]; // left part
char R[32+1]; // right part
for (int i = 0; i < 32; i++) {
L[i] = IP_M[i];
R[i] = IP_M[i + 32];
}
L[32] = '\0';
R[32] = '\0';
printf("IP_M: %s\n", IP_M);
printf("L: %s\n", L);
printf("R: %s\n", R);
}
However, there's no apparent reason why you need to do the middle step with the 64 characters array. You could as well put that one in a union and save the copy (although then the individual left/right strings won't be null terminated). Example:
#include <stdio.h>
#include <stdlib.h>
typedef union
{
char data [64+1];
struct
{
char left[32];
char right[32];
char zero;
};
} ip_t;
ip_t *start_inital_permutation(const char *input) {
size_t count=0;
ip_t* obj = malloc(sizeof(ip_t));
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
obj->data[i * 8 + j] = input[count++];
}
}
obj->data[64] = '\0';
return obj;
}
int main()
{
const char input[] = "1100110000000000110011001111111111110000101010101111000010101010";
ip_t *IP_M = start_inital_permutation(input);
printf("IP_M: %s\n", IP_M->data);
printf("L: %.32s\n", IP_M->left);
printf("R: %.32s\n", IP_M->right);
}
Using printf with "%s" assumes the value is a zero terminated string (AKA NULL terminated string).
I.e. a pointer to a sequence of chars, ending with a \0 char.
In your case when printf attempts to print L it prints char, and after the 32 chars that belong to L it continues. It happened to be that R is following L in memory, and so the content of R is also dumped. If the next byte in memory following R was not a 0, you would see even more characters printed. This behavior is dependent on the [possibly atrbitarary] content of your memory.
How to handle the issue (2 ways):
1. You can either increase the size of L and R to 33, and assign the last char to \0:
char L[33]; // left part
char R[33]; // right part
/* ... */
L[32] = '\0';
R[32] = '\0';
2. Or specify to printf the length of the strings (32) like this:
/*----------vvv-------*/
printf("L: %.32s\n", L);
printf("R: %.32s\n", R);
In the later case keep in mind that L and R are not "regular" C strings, which are expected to be zero terminated (at least as far as it concerns common functions like strlen, strcmp etc.).

C how to convert to hexadecimal integer

im writing a code for converting a number to hexadecimal and im getting a random numbers as result.
at first i succeed to convert the number but it was in a reversed order (the first mod needs to be the last number or letter).
the code is a part (for cases of %x) from a big project that is kind of implementation of sprintf (so sprintf or printf are not allowed obviously). so the buffer is for composing a string without any placeholders.
thank u in advance.
here's my code:
int num = *(int*)ptrs[counter];
int tempnum=num;
int mod=0;
int length =0;
for(int i=0;tempnum !=0;i++)
{
length++;
tempnum /= 16;
}
int array[length];
for(int i= length; i>0;i--)
{
mod = num%16;
num = num/16;
array[i] = mod;
}
for(int i=0;i<length;i++)
{
if(array[i]<10)
*buffer = array[i]+ '0';
else
*buffer = array[i] -10 + 'a';
buffer++;
}
The for loop of calculating array[i] should change to:
for(int i = length-1; i>=0;i--) // i from (length - 1) to 0 instead of from length to 1.
{
mod = num%16;
num = num/16;
array[i] = mod;
}
You do not need to change the buffer pointer. You can use:
for(int i=0;i<length;i++)
{
if(array[i]<10)
buffer[i] = array[i]+ '0';
else
buffer[i] = array[i] + 55;
}
then do not forget at the null character at the end of buffer:
buffer[length] = '\0';
I do not see the declaration of buffer in your code, so i propose the solution above for the declaration:
char buffer[length+1];
for(int i= length; i>0;i--)
{
mod = num%16;
num = num/16;
array[i] = mod;
}
mistakes at array[i] to array[i-1].
buffer = array[i] + '87';
I suggest you use:
buffer = array[i]-10 + 'a';
printf("%i", (int)[any hexadecimal number]);
would print the integer form of this '[any hexadecimal number]' number

Why is my output different depending on how the variable len is defined?

Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int len = 3; // length of word
char * word = "cat"; // word to be sorted
char sortedWord[len];
int i, j, temp;
// store chars from 'word' to an array 'sortedWord[]'
for (i = 0; i < len; i++) {
sortedWord[i] = *word;
word++;
}
// sort the array using bubble sort
for (i = 0; i < len - 1; i++) {
for (j = 0; j < len - i - 1; j++) {
if (sortedWord[j] > sortedWord[j + 1]) {
temp = sortedWord[j];
sortedWord[j] = sortedWord[j + 1];
sortedWord[j + 1] = temp;
}
}
}
printf("%s\n", sortedWord);
}
The focus of this question is the variable 'len'. If I were to define len to be equal to 3, then the output is as expected (i.e. "act"). However, I want to be able to find the length without explicitly defining it.
I have tried to define len as:
int len = strlen (word);
However, the output is not as expected. It would give me results such as actW?, actX?, and so on.
This same behavior occurs when I try to define len as:
int len;
for (len = 0; *word != '\0'; len++) {
word++;
}
Surprisingly, if I were to print the the variable len right after explicitly defining it, it would also behave the same way.
int len = 3;
printf("Length: %d\n", len); // will cause the output to be different
I am sure that I am missing a fundamental concept, but I am not sure on an approach to resolve this problem. Thanks in advance!
Your storeWord is not null terminated causing undefined behavior, add the null terminator and it will no longer behave erratically.
And also, if you increment the word pointer, it will end up pointing to the null terminator of the original string, so don't do that. Instead, use the index to access elements.
char sortedWord[len + 1]; // One more for the '\0'
int i, j, temp;
// store chars from 'word' to an array 'sortedWord[]'
for (i = 0; i < len; i++) {
sortedWord[i] = word[i];
}
storeWord[len] = '\0';
One more thing, when writing pointers to string literals, use const to prevent accidentally modifiying them, since that is undefined behavior too, so
const char *word = "cat";

Trying to terminate a char array and print afterwards

I'm making a char array binary representations of a number. I want to terminate the end of the string with '\0'. It prints the array find aside from the intended garbage value.
However when I try to terminate the array, specifically the index of the garbage value, it won't print out my string.
int main(void)
{
char s[8] = {0};
printing_binary(s, 8, 2);
}
void printing_binary(char *s, int length, unsigned n){
for(int i = 0; i < length; i++){
if(1 & (n >> i)){
s[i] = '1';
}
else{
s[i] = '0';
}
}
//Trying to terminate my string
//s[length] = '\0';
printf(s);
}
This code will print out something like 01000000}.
However if I uncomment out s[length] = '\0', it prints nothing/the program stops executing. I've tried printing out "Hello world" after everything.
If you define your result array as char s[8], then you must not write anything at position 8 like in s[length] = 0x0 with length==8, because this exceeds the array length. Try:
char s[9] = {0};
printing_binary(s, (9-1), 2);
You have an 8 bit length which you fill up with the values. For example the value 2 is 00000010 Since you have filled up your string array, you have no room for the ending character. If you define the array size as length+1, then it will work.
int main(void)
{
char s[9] = {0}; // Note size is length+1
printing_binary(s, 8, 2);
}
void printing_binary(char *s, int length, unsigned n){
for(int i = 0; i < length; i++){
if(1 & (n >> i)){
s[i] = '1';
}
else{
s[i] = '0';
}
}
//Trying to terminate my string
s[length] = '\0'; // s must be an array of size greater than length
printf(s);
}
If you don't want to add a null terminator, you just have t modify the printf slightly.
int main(void)
{
char s[8] = {0};
printing_binary(s, 8, 2);
}
void printing_binary(char *s, int length, unsigned n){
for(int i = 0; i < length; i++){
if(1 & (n >> i)){
s[i] = '1';
}
else{
s[i] = '0';
}
}
//Trying to terminate my string
//s[length] = '\0';
printf("%.*s", length, s);
}
Another way is to declare i outside the loop. This can be useful if for some reason your logic breaks out of the loop before reaching length
int i;
for ( i=0; i < length; i++ ) {
...
}
s[i] = '\0';

Something is wrong with this C code to reverse string, but I dont know what ? please help

I am beginnner to programming. I wrote this little program to reverse a string. But if I try to reverse a string which is less than 5 characters long then it gives wrong output. I cant seem to find whats wrong.
#include<stdio.h>
#include<string.h>
int main()
{
char test[50];
char rtest[50];
int i, j=0;
printf("Enter string : ");
scanf("%s", test);
int max = strlen(test) - 1;
for ( i = max; i>=0; i--)
{
rtest[j] = test[i];
j++;
}
printf("Reversal is : %s\n", rtest);
return 0;
}
You are not terminating the reversed string with a 0. (all strings in C are 0-terminated)
In this case, the printf will (likely, depending on the unitialized contents of the rtest array) create a buffer overflow.
Add a rtest[max+1]=0; after the for loop and everything should be fine.
Otherwise you can declare char rtest[50] = {0} (this will initialize the whole array with 0s).
rtest is unitialized.
You should add rtest[j] = '\0'; after the for loop to say where the string ends
void reverse(char* str)
{
int len = strlen(str);
for (int i = 0; i < len / 2; ++i) {
char tmp = str[i];
str[i] = str[len - 1 - i];
str[len - 1 - i] = tmp;
}
}

Resources