Issues with a Caesar Cipher - c

So the main issue is that the addition of (-5 to 4) to the characters in the entered string is all messed up to show possible words that were encrypted. When the loop runs the enter characters are not the starting point thus throwing everything else off. Additionally, I cannot get the repeat = false statement to register.
#include<stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
int main()
{
char encrypted_string[100];
char z;
char stop[]="STOP";
int x=-5, y, len;
bool repeat = true;
while (repeat)
{
printf("Enter the encrypted word (type STOP to quit) : ");
fgets(encrypted_string, 100, stdin);
if (strcmp(encrypted_string, stop)== 0)
{
repeat = false;
}
//len=strlen(encrypted_string);
while (x < 5)
{
for (y = 0; encrypted_string[y] != '\0'; y++)
{
z = encrypted_string[y];
if (z >= 97 && z <= 122)
{
z=z+x;
if (z < 97)
{
z=z+(122-97)+1;
}
encrypted_string[y] = z;
}
else if (z >= 65 && z <= 90)
{
z=z+x;
if (z < 65)
{
z=z+(90-65)+1;
}
encrypted_string[y] = z;
}
}
printf("For shift of %d, decrypted word is %s\n", x++, encrypted_string);
}
}
return 0;
}

char stop[]="STOP";
fgets(encrypted_string, 100, stdin);
if (strcmp(encrypted_string, stop)== 0)
fgets() leaves the trailing newline in the buffer, so this will never be true if the user hit enter at the end of the line.
if (z >= 97 && z <= 122)
These look a bit like magic numbers, probably better to write 'a' and 'z' instead.
if (z >= 97 && z <= 122) {
z=z+x;
if (z < 97)
What if the increment x is positive? z could go over 122.
Actually, why is it named x? It's the shift offset, so call it that.
Similarly, y is an index, so perhaps i instead. Especially confusing is that you have x, y and z that are three totally different things.
while (x < 5) {
for (y = 0; encrypted_string[y] != '\0'; y++) {
...
encrypted_string[y] = z;
You're modifying the same string you read again on the next iteration. For the input foo, it does a shift of -5 giving ajj, then a shift of -4 from that, giving wff, etc.

Related

Can someone explain to me how the modulo character works to output a leading zero

This is the original question:
Create a function that displays all different combination of two digits between 00
and 99, listed by ascending order.
This was how a fellow student did it. It compiles. So all the first single digit outputs have to have a leading zero. I dont understand how he achieved it. Can someone explain to me this a%10 +0 part and how that works to print leading zeros? Thank you in advance.
void ft_print_comb2(void)
{
int x;
int y;
enter code here
x = 0;
while (x < 99)
{
y = x + 1;
while (y < 100)
{
output_format(x, y);
printlines(x, y);
y++;
}
x++;
}
}
void output_format(int x, int y)
{
if (!((x == 99 && y == 99) || (x == 0 && y == 1)))
{
write(1, ", ", 2);
}
}
void printlines(int x, int y)
{
char xmodule;
char xdiv;
char ymodule;
char ydiv;
xmodule = (x % 10 + '0');
xdiv = (x / 10 + '0');
ymodule = (y % 10 + '0');
ydiv = (y / 10 + '0');
write(1, &xdiv, 1);
write(1, &xmodule, 1);
write(1, " ", 1);
write(1, &ydiv, 1);
write(1, &ymodule, 1);
}
For numbers between 0 and 100, x%10 + '0' is the ASCII value of the lowest digit of x, and x/10 + '0' is the ASCII value[1] of the tens digit (or 0 if the number is less than 10). '0' is the ASCII value that represents the character 0, and x%10 is the remainder when dividing x by 10. That's the trick used by your friend's code.
[footnote 1] (or more accurately, the character code from the character set of the execution environment which may or may not be ASCII).
However, the code written is quite complicated, and formatting numbers for output (including leading zeros) is provided by the standard library. Loops that range between two numbers can be conveniently described using a for loop. The function write used by the program is POSIX, and not part of the C standard library.
Here's a complete version using printf:
#include <stdio.h>
int main(int argc, char *argv[]) {
for (int x = 0; x < 100; x++) {
for (int y = x+1; y < 100; y++) {
if (y!=1) printf(", "); // skip comma for the first pair output.
printf("%02d %02d", x, y);
}
}
printf("\n");
return 0;
}

In this code Why Write() doesn't work with Int?

I cannot understand why this code doesnt work. it works fine with printf but i cannot get it to work with write...
#include <stdio.h>
#include <unistd.h>
int ft_putchar(char a,char b,char c){
write(1,&a,1);
write(1,&b,1);
write(1,&c,1);
return(0);
}
int main()
{
int x = 0;
int y, z;
while(x <= 9){
y = x + 1;
while(y <= 9){
z = y + 1;
while(z <= 9){
ft_putchar(x,y,z);
z++;
}
y++;
}
x++;
}
return 0;
}
there are no error outputs
You need to convert ASCII to its digit equivalent before writing.
example 5 = '5' +'0'
As of now you are writing the ASCII values to terminal.
int ft_putchar(char a,char b,char c){
a += '0';
b += '0';
c += '0';
write(1,&a,1);
write(1,&b,1);
write(1,&c,1);
return(0);
}
i want to print them like this but in the end it should have nothing
578, 579, 589, 678, 679, 689, 789, instead of 789, it should be 789 im
using c= ','; write(1,&c,1); c= ' '; write(1,&c,1);
You need to pass the delimiter to ft_putchar function,
int ft_putchar(char a,char b,char c, char del){
a += '0';
b += '0';
c += '0';
write(1,&a,1);
write(1,&b,1);
write(1,&c,1);
write(1,&del,1);
return(0);
}
int main()
{
int x = 0;
int y, z;
while(x <= 9){
y = x + 1;
while(y <= 9){
z = y + 1;
while(z <= 9){
if (x == 7 && y == 8 && z == 9)
ft_putchar(x,y,z, ' ');
else
ft_putchar(x,y,z, ',');
z++;
}
y++;
}
x++;
}
return 0;
}
When you used printf, I am guessing you used:
printf("%d %d %d",a,b,c);
So you are explicitly telling the function to interpret the variables as numbers, and print those. When you use write, it assumes that what you are using is a char. This means this would be the same as:
printf("%c %c %c",a,b,c);
Try that - you will see you still get blanks. That is because you are not interpreting the variables as characters, and so converting the numbers 1..9 to their ASCII letter value. These are not normal characters and will appear blank.
This would be the same if you used char in main instead of int. Your best option to convert a normal integer to a the ASCII value that prints said integer is via the answer by Kiran,
myInt += '0'; //Only works for numbers than 0..9. You may has well have used char to save space.
since all ASCII characters for numbers are consecutive.

Printing A-Z using putchar() with tolower() or toupper() stops the loop at the first char

Trying to iterate through ASCII characters
I want to print all the A-Z characters in lowercase but I get only the first char printed.
#include <stdio.h>
int main()
{
for(int x = 'A'; x <= 'Z'; x++)
{
x = tolower(x);
putchar(x);
}
return 0;
}
Output
a
The problem with your approach is that your are modifying the variable that is
used as the running variable for the loop.
Take a look at the ASCII Table and you'll notice that the upper case
letters have an integer value smaller than the lower case letters.
So in the first iteration, x is assigned to A, then you do
x = tolower(x);
which changes the value of x from A to a. The integer value of a is 97,
which is greater than the integer value of Z (which is 90). When the next
iteration is started x++ is executed, which make x even larger than 90, so the condition
x <= 'Z'
will be evaluated to false, hence the loop stops.
So, don't change the variable that your are using as the running variable for the
loop. You can do either
for(int x = 'A'; x <= 'Z'; x++)
{
int lower_x = tolower(x);
putchar(lower_x);
}
or
for(int x = 'A'; x <= 'Z'; x++)
{
putchar(tolower(x));
}
In both cases x is only modified by the loop itself and you don't run into
the problem you've had.
Note that while
int main()
{
for(int x = 'A'; x <= 'z'; x++) // Notice (x <= 'Z') > > (x <= 'z')
{
x = tolower(x);
putchar(x);
}
return 0;
}
gives you the same results in this case, this is not in general the correct
solution, because it is still modifying the x variable outside the
loop-construct. The values of x
will be
First iteration x == 'A'
Second iteration x == 'b'
Third iteration x == 'c'
...
Like I said, the end result might the same, but this is only a coincidence. Image
you have this task: print the values multiplied by 100 from 10 to 20
If you do
for(int x = 10; x <= 20; x++)
{
x = x * 100;
printf("%d\n", x);
}
You will have the same situation as before. But the solution
for(int x = 10; x <= 200; x++)
{
x = x * 100;
printf("%d\n", x);
}
would print completely incorrect values. Like for your problem, the correct
solution would be not to modify x in the block
for(int x = 10; x <= 20; x++)
{
printf("%d\n", x * 100);
}
Problem is in the line
x = tolower(x);
After the first iteration, it overrides x to a bigger value (because the codes of lowercase characters are bigger than uppercase characters), thus the loop doesn't continue any further.
int x = 'A' // 65
A is equivalent to 65.
x <= 'Z' // 90
Z is equivalent to 90.
1st Iteration:
The expression x <= 'Z' or 'A' <= 'Z' is the same as 65 <= 90 which is true.
But then the line
x = tolower(x);
Overrides x from 'A' (65) to 'a' (97)
So, after printing the first char which is 'a', the loop increments 97 (=> 98) then iterates again
2nd Iteration:
Is x <= 'Z' which is 98 <= 90? No. That's false. Therefore the loop breaks.
To fix this, you need to not override the variable which the loop depends on to continue execution. Try storing the lowercase result in another variable other that x
#include <stdio.h>
int main()
{
for(int x = 'A'; x <= 'Z'; x++) // jumps from 'A'(65) to 'B'(66) to ... in order.
{
char small = tolower(x);
putchar(small);
}
return 0;
}
Or you could also just print the return value right away putchar(tolower(x));
Do note that the for loop
for(int x = 'A'; x <= 'Z'; x++)
{
x = tolower(x);
putchar(x);
}
is just syntactic sugar for a while loop - here equivalent to
{
int x = 'A';
while (x <= 'Z') {
x = tolower(x);
putchar(x);
x ++;
}
}
By the time it reaches the x ++, the value is 'a' i.e. 97, and after the increment, it will be 'b' i.e. 98. Since 'b' <= 'Z' (98 <= 90) is false, the iteration stops.
Many newcomers to C think for is some magical structure, as it is in some other programming languages, and that's where they go wrong.
P.s. had you written putchar(tolower(x)); your program would have worked.

Cursor moving erratically (C)

I'm having some trouble doing a Nim game program. So far I have a program that will show a pyramid of pipes. It looks like the "start position" pyramid on this picture.
http://www.mathsisfun.com/puzzles/images/b-nim.gif
Anyways, I'm having trouble moving around this, whenever I try moving around, my cursor will move in completely erratic ways. Thid will make the game totally unplayable. I'm not sure if it is a problem with my counting variables or even some smaller thing I'm totally missing, anyways here's what I have:
#include <stdlib.h>
int nim()
{
char *tab;
if ((tab = malloc(sizeof(char) * 20 + 4)) == NULL)
return (-1);
tab = " | \n ||| \n ||||| \n |||||||\n"; /* this is indeed a nasty way to do it :P */
putstr(tab);
}
int move_normally()
{
char bffr[10];
int x;
int y;
x = 0;
y = 0;
while (42 && x <= 6 && y <= 3)
{
read(0, bffr, 10);
putstr(tgoto(tgetstr("cm", NULL), x, y);
if (bffr[2] == 66 && y <= 3 && x <= 6)
y++
else if (bffr[2] == 65 && x <= 6 && y <= 3 && (y - 1) >= 0)
y = y - 1;
else if (bffr[2] == 67 && x <= 6 && y <= 3)
x++
else if (bffr[2] == 68 && x <= 6 && y <= 3 && (x - 1) >= 0)
x++
}
}
So, is there something I'm missing here? everything else works almost perfectly and I can't get my hands on why this is giving trouble. Also, are there any other ways to do this? I'm open to any alternative way.

Check that an array contains only numbers

I'm having a problem where I am wanting to go through an array and check that only positive numbers have been entered. I know that it is possible to use isDigit from ctype.h but I'd rather construct something myself. The way I think it is possible, is to iterate through each element of the array and see if the value stored there is between 0 and 9, but it isn't working. This is my code so far:
char testArray[11] = {'0'};
printf("Enter a string no longer than 10 chars");
scanf("%s", testArray);
int x;
int notanumber = 0;
for (x = 0; x < 11; x++) {
if ((testArray[x] < 0) || (testArray[x] > 9)) {
notanumber++;
}
}
printf("%i", notanumber);
It is not working because 0 and 9 are integers not characters.
Change your if condition to
if((testArray[x] >= '0') || (testArray[x] <= '9')){ ... }
to check the digits from 0 to 9.
this line
if((testArray[x] < 0) || (testArray[x] > 9)){
should be replaced by
if((testArray[x] < '0') || (testArray[x] > '9')){

Resources