Print a Char Array of Integers in C - c

For class, I am required to create a function that converts an Integer into it's corresponding Binary number. However, I am forced to use the given main and parameters for the to_binary function. The whole problem requires me to print out the 32 bit binary number, but to break it up, I am just trying to print out the Char Array, that I thought I filled with Integers (perhaps the issue). When I do compile, I receive just a blank line (from the \n) and I am wondering how I can fix this. All I want to do is to be able to print the binary number for 5 ("101") yet I can't seem to do it with my professor's restrictions. Remember: I cannot change the arguments in to_binary or the main, only the body of to_binary. Any help would be greatly appreciated.
#include<stdio.h>
void to_binary(int x, char c[]) {
int j = 0;
while (x != 0) {
c[j] x = x % 2;
j++;
}
c[33] = '\0';
}
int main() {
int i = 5;
char b[33];
to_binary(i,b);
printf("%s\n", b);
}

This is the answer to your question.
void to_binary(int x, char c[]) {
int i =0;
int j;
while(x) {
/* The operation results binary in reverse order.
* so right-shift the entire array and add new value in left side*/
for(j = i; j > 0; j--) {
c[j] = c[j-1];
}
c[0] = (x%2) + '0';
x = x/2;
i++;
}
c[i]=0;
}

the problem is in the code below:
while (x != 0) {
c[j] = x % 2; // origin: c[j] x = x % 2; a typo?
j++;
}
the result of x % 2 is a integer, but you assigned it to a character c[j] —— integer 1 is not equal to character '1'.
If you want to convert a integer(0-9) to a character form, for example: integer 7 to character '7', you can do this:
int integer = 7;
char ch = '0' + integer;

One of the previous answers has already discussed the issue with c[j] x = x % 2; and the lack of proper character conversion. That being said, I'll instead be pointing out a different issue. Note that this isn't a specific solution to your problem, rather, consider it to be a recommendation.
Hard-coding the placement of the null-terminator is not a good idea. In fact, it can result in some undesired behavior. Imagine I create an automatic char array of length 5. In memory, it might look something like this:
Values = _ _ _ _ _
Index = 0 1 2 3 4
If I were to populate the first three indexes with '1', '0', and '1', the array might look like so:
Values = 1 0 1 _ _
Index = 0 1 2 3 4
Let's say I set index 4 to contain the null-terminator. The array now looks like so:
Values = 1 0 1 _ \0
Index = 0 1 2 3 4
Notice how index three is an open slot? This is bad. In C/C++ automatic arrays contain garbage values by default. Furthermore, strings are usually printed by iterating from character to character until a null-terminator is encountered.
If the array were to look like it does in the previous example, printing it would yield a weird result. It would print 1, 0, 1, followed by an odd garbage value.
The solution is to set the null-terminator directly after the string ends. In this case, you want your array to look like this:
Values = 1 0 1 \0 _
Index = 0 1 2 3 4
The value of index 4 is irrelevant, as the print function will terminate upon reading index 3.
Here's a code example for reference:
#include <stdio.h>
int main() {
const size_t length = 4;
char binary[length];
size_t i = 0;
while (i < length - 1) {
char c = getchar();
if (c == '0' || c == '1')
binary[i++] = c;
}
binary[i] = '\0';
puts(binary);
return 0;
}

#include<stdio.h>
int binary(int x)
{
int y,i,b,a[100];
if(x<16)
{
if(x%2==1)
a[3]=1;
if(x/2==1||x/2==3 || x/2==5 || x/2==7)
a[2]=1;
if(x>4 && x<8)
a[1]=1;
else if(x>12 && x<16)
a[1]=1;
if(x>=8)
a[0]=1;
}
for(i=0;i<4;i++)
printf("\t%d",a[i]);
printf("\n");
}
int main()
{
int c;
printf("Enter the decimal number (less than 16 ):\n");
scanf("%d",&c);
binary(c);
}
this code might help it will simply convert the decimal number less than 16 into the 4 digit binary number.if it contains any error than let me know

Related

While loops and arrays causing very odd behaviour...maybe a memory mixup

I'm tired of this tom-foolery occurring during runtime , although I'm sure we all are, when our programs screw up at runtime in the most obscure ways.
Getting to the point, the entire source code is a bit large to place here, but still <200 lines, so that's here . Use it if running the program, since the code I will post below is just functions, where I think the error lies.
Context : This is a sort of shift cipher with 8 different shifts taken using an 8 digit pin.
The issue is strange. Basically, the encrypt() function works correctly always -I've matched it by doing the algorithm for myself on paper ; for example, ABC is correctly encoded to 3c 45 46 -6f when the Pin is 12345678.
The strange issues are with the decrypt() function.
When the program is run for the first time, trying to run decrypt() on a valid ciphertext-pin pair always returns nothing except a /n (newline) . When tried with a different valid pin-ciphertext pair, after a successful run of encrypt() is done first, the decrypt() function just returns either the same message which was just encrypted or some other random output from the previously encoded message.
Without further ado, the legendarily screwed up decrypt function which I have rebuilt thrice now -
void decrypt()
{
printf("\n");
int *digits = pin(); int d[8];
getchar();
for (int i=0;i<8;i++)
d[i] = *(digits + i); //puts each digit in a local array.
printf("\nEnter encoded message -\n\n");
getchar();
int j; char ch, msg[3002];
for(int i=0; i < 3000;i++)
{
scanf("%x",&j);
if(j==-111){
msg[i] = '\0'; //terminates string with \0
break;
}
else{
if(ctln(i)==1)
ch = j - d[2];
else if(fib(i)==1)
ch = j + d[4];
else if(luc(i)==1)
ch = j - d[0];
else if(pent(i)==1)
ch = j + d[6];
else if(hex(i)==1)
ch = j - d[3];
else if(prm(i)==1)
ch = j + d[7];
else {
if(i%2 == 0)
ch = j - d[1];
else
ch = j + d[5];
msg[i] = ch;
}
}
}
printf("\nDecrypted message -\n\n");
puts(msg);
}
For context, as well as finding the culprits here, do make sure to read the full code here , with the pin() returning a pointer to a static int array holding all 8 digits , as well as the ctln() , fib(), luc(), pent(), hex(), prm() [ which check if position value i of char in message is a part of Catalan, Fibonacci , Lucas, Pentagon, Hexagon, Prime number series. More here.
Edit 1
I have already tried keeping different variable names, and some other things I can't fully recall. Also, because it is very relevant, below is the pin() function:
int *pin()
{
int num,q=0; static int pins[8];
printf("Enter 8-digit PIN : ");
scanf("%d", &num);
for(register int i = 10000000 ; i >= 1 ; i = (i/10)) // i is position of digit.
{
int d = ((num - (num % i)) / i); // d stores 'digit' ( divides quotient of (num % i) by i)
pins[q] = d; q++;
num = (num - ( d * i ));
}
return pins ; // pointer to static array storing digits of PIN
}
Edit 2
I had wrongly assigned pins[6] rather than pins[8] in the original code, I have corrected it but am still facing the same errors.
Edit 3
After correcting the mistake pointed out by MikeCAT, it now ignores the first character when deciphering.
Edit 4
The getchar() before scanf() was to blame, removing it fixes the last issue too. Thanks #MikeCAT !
In your decrypt() function, msg[i] = ch; is executed only if none of the functions ctln, fib, luc, pent, hex, prm returned 1.
Therefore, uninitialized value of non-static local variable msg, which is indeterminate, may be used for printing and undefined behavior may be invoked.
The part
msg[i] = ch;
}
should be
}
msg[i] = ch;
as it is done in encrypt() function.

N permutations of string (with repetitions)

I have to print first n permutations with repetitions of a string.
String is formed with characters 'a','b','c','d','e','f'.
For example, first 10 permutations would be: aaaaaa,aaaaab,aaaaac,aaaaad,aaaaae,aaaaaf,aaaaba,aaaabb,aaaabc,aaaabd.
This is my failed attempt:
int main()
{
FILE *c;
c = fopen("C:\\Users\\Korisnik\\Desktop\\tekst\\permutacija.txt", "w");
char s[6] = "abcdef";
char t[6] = "aaaaaa";
s[6] = '\0';
t[6] = '\0';
int k = strlen(t);
int m = k;
int n;
scanf("%d", &n);
int br = 0;
int i = 0;
while (br < n) {
i = 0;
while (i < 6) {
t[k-1] = s[i];
fprintf(c, "%s ", t);
fprintf(c, "\n");
i++;
br++;
if (br == n) {
exit(1);
}
}
t[k-1] = 'a';
k--;
if (k < 0) {
k = m;
}
}
return 0;
}
And my output for first 10 permutations is:
aaaaa
aaaaab
aaaaac
aaaaad
aaaaae
aaaaaf
aaaa
aaaaba
aaaaca
aaaada
Any suggestions?
(Showing a different idea)If you look carefully you will see that all the permutations are the numbers in base-7. Consider a as 0, b as 1 and so on. So for every number 1..n you will convert it into base 7 and write it (By write it I mean, in place of 0 you put a,1 - b etc). That will give you the required result. (Ofcourse in conversion you will have to append 0 to the left of the number as per number of digits you want to show). There are problems in your code:
char s[6]="abcdef";
is legal in C.
s[6]=0;
This is not as you are accessing array index out of bound which is Undefined behavior. strlen(t) is undefined behavior as t is not NUL terminated.
Also you have fprintf(c,"%s ",t); in your code - this also leads to undefined behavior, it also expects a char* which points to a nul terminated char array. This will make your realize that how irrelevant it is to have something like this
char s[6]="abcdef";
Long story short, use char s[7]="abcdef"; (same applies to t also).

Affine Cipher in C doesn't work correctly

Disclaimer: Whatever is below, it's related to Affine Cipher. For whomever doesn't know it, it's a encrypting method that uses a mathematical function Ax+B to shift each letter in a given plaintext according to the letter's index in the alphabet.
I've written a code that encrypts and decrypts a given plaintext or ciphered text using Affine Cipher. It consists of these three functions:
char *encryption(char Plaintext[MAXSIZE], int A, int B);
int modularinverse(int number, int modulo);
char *decryption(char Ciphered[MAXSIZE], int A, int B, int inverse);
The part that concerns me sites in the decryption function. Around three or four letters are miss-calculated.
Let's consider the following plaintext: "a b c d e"
Using the encryption function:
char *encryption(char Plaintext[MAXSIZE], int A, int B) {
static char Ciphered[MAXSIZE];
int i;
int y;
int index;
for (i = 0; i < strlen(Plaintext) - 1; i++) {
if (Plaintext[i] == ' ') {
Ciphered[i] = ' ';
} else {
index = (int)Plaintext[i] - 'a';
y = (A * index + B) % 26;
Ciphered[i] = (char)y + 97;
}
}
return Ciphered;
}
it turns the plaintext into: "f m t a h". Which is correct.
Decrypting the plaintext should obviously give: "a b c d e". But instead, it gives: "a b c J e".
char *decryption(char Ciphered[MAXSIZE], int A, int B, int inverse) {
static char NewPlaintext[MAXSIZE];
int i;
unsigned int x;
int y;
int index;
for (i = 0; i < strlen(Ciphered); i++) {
if (Ciphered[i] == ' ') {
NewPlaintext[i] = ' ';
} else {
index = (int)Ciphered[i] - 'a';
x = inverse * (index - B) % 26;
NewPlaintext[i] = (char)x + 97;
}
}
return NewPlaintext;
}
The letter d is miss-calculated for a reason I don't know. Printing the values of variables index, inverse, B and x for each one of the characters f m t a h will respectively return this:
5 15 5 0
12 15 5 1
19 15 5 2
0 15 5 -23
7 15 5 4
First column represents indexes of the letters f m t a h.
Second column represents the inverse of A=7, which is 15. (Totally harmful, you may ignore it).
Third column represents B which is a constant for now (You may ignore it).
Fourth column represents x which is the result of inverse*(index-B) % 26. Adding 97 (ASCII number of 'a') to each of number in this column will result to the ASCII number of each letter.
i.e 0+97 = 97 which is 'a'. By consequence Decryption(f)=a.
But if you can notice. the result of x for the letter 'a' is -23. -23+97=74 which is J in ASCII. It should rather be 100 as it's the ASCII number for d. Therefore the result of x should rather be 3, not -23.
The reason behind this miss-calculation is buzzing me and I haven't figured out what's causing it.
Your code has few issues which are causing this strange behavior;
Don't use int type if you are dealing with character. Use char
In decryption() handle if the value of x is negative.
you can modify your decryption() like this.
char *decryption(char Ciphered[MAXSIZE],int A, int B, int inverse)
{
static char NewPlaintext[MAXSIZE];
char x;
char index;
for(int i=0;i<strlen(Ciphered);i++)
{
if(Ciphered[i]==' ')
{
NewPlaintext[i]=' ';
}
else
{
index=(int)Ciphered[i] - 'a';
x=inverse*(index-B) % 26;
if(x < 0)
{
// add 26 to take care of negative values; since you are using %
x += 26;
}
NewPlaintext[i]=(char)x+97;
}
}
return NewPlaintext;
}
I tested it few entries and it works fine.
Hope this helps.
Your code has several problems:
you stop before the end of the string: i<strlen(Plaintext)-1
you do not null terminate the destination strings.
your return a pointer to static storage: only one string can be encrypted/decyphered at a time.
depending on the values, you may take the modulo of negative numbers, which will be negative too. Use this instead: x = ((inverse * (index - B) % 26) + 26) % 26;

Swapping elements of char array in C

I have this code:
char *sort(char *string){ //shell-sort
int lnght = length(string) - 1; // length is my own function
int gap = lnght / 2;
while (gap > 0)
{
for (int i = 0; i < lnght; i++)
{
int j = i + gap;
int tmp =(int)string[j];
while (j >= gap && tmp > (int)string[j - gap])
{
string[j] = string[j - gap]; // code fails here
j -= gap;
}
string[j] = (char)tmp; // and here as well
}
if (gap == 2){
gap = 1;
}
else{
gap /= 2.2;
}
}
return string;
}
The code should sort (shell-sort) the characters in the string, given the ordinal value (ASCII value). Even though the code is pretty simple, it still fails at lines I've commented - segmentation fault. I've spent plenty of time with this code and still can't find the problem.
As you say in comment , you call our function like this -
char *str = "test string";
sort(str);
String literal is in read-only memory and creates a pointer str to that, thus it cannot be modified , and your function modifies it . Therefore ,it can result in segmentation fault .
Declare like this -
char str[] = "test string";
In situations like this look at your statements not so much as executable code, but as mathematical boundary conditions. I've replaced the monstrous name lnght with length for readability purposes.
Here are the relevant conditions that affect the value of j when entering the while loop, relative to the length.
i < length;
gap = length / 2;
j = i + gap;
Now we plug in a value. Consider the case where length == 10. Then presumably the maximum index in your array is 9 which is also the highest value that i can take on.
Then we also have that gap == 5 and so after entering the while loop j == i + gap == 9 + 5. Clearly 9 + 5 > 10. The rest is left as an exercise to the programmer.
How do you test your function? With a static string (i.e. char *buffer = "test string";) ?
Because on first loop at least j and j-gap should be inside the string boundaries. So if you get a segfault I guess it is because of a bad string (statics can't be modified).
Replacing length() by strlen() and calling it with a well-created test string lead me to a valid result:
"adgfbce" → "gfedcba"

Converting a char to an int for int arithmetic in java

i have a bit of strange confusion happening when trying to convert my char variables from my char array into ints.
Here is my code:
public class Luhn {
private String cardNumber;
private char[] cardArray;
public Luhn(String cardNumber) {
this.cardNumber = cardNumber;
cardArray = new char[cardNumber.length()];
for (int i = 0; i < cardNumber.length(); i++) {
cardArray[i] = cardNumber.charAt(i);
}
public void calculation() {
for(int i = cardArray.length-1; i >= 0; i-=2) {
char y = cardArray[i];
int x = (int) (cardArray[i] * 1);
if(x > 9) {
//int total = 0;
}
}
}
I keep getting strange outputs in x. Something like 58. I'm accessing the array backwards and retrieving every 2nd number back to the front of the array. I basically want x to be whatever the number is in each array element. I know with this small piece of code it will overwrite x continuously, but i want it to be the number designated in the char array, not some random number not matching my array elements. The problem is in the calculation method where i try and convert the char to int.
Please help
Thanks.
For Example;
You can do
(int)(cardArray[i] - '0')
to convert a single digit to a number.
The reason you can do this is because each char is a number.
'0' = 48
'1' = 49
'2' = 50
'3' = 51
...
'9' = 57
Subtraction the value for 0 gets you the integer value for each of the characters.
chars are actually numbers that represent chars. if you want to convert it into an int, subtract the 0 char
int x = (int) (cardArray[i] - '0');
You could use Character.getNumericValue(char), See JavaDoc here

Resources