Transposition cipher too long compilation - c

I need to do a program that decodes Transposition cipher. On start I have one word, which is in encrypted text. the length of the key is equal to the -1 length of the received word. key is random.
Examples:
input text:Uniz isvrh tiesiime ffrmfbi jz tpywjhpf gx ucs zgvey eoj e igpg himua xgxfx qbxo xgw b xihapbx vftx jt xik jpxq pl eo owpygfrit zvjgrhri
input word: mark
output:They could scarcely believe it possible at two yards and a half below water mark was a regular rent in the form of an isosceles triangle
input text:Qr oc cvtmxen ev Rga Asto vlg uwiuxksp acw cx kxu lgmilv
input word:was
output:On my arrival at New York the question was at its height
input text: Rt kolniz qufkbnx R gjvoczkm zqk kgobzkwin ul cnn suwyckx
input word: effect
output:In effect however I admitted the existence of the monster
For examples 1 and 2 the program compiles quite quickly, but for example 3
the program compiles for a very long time because i have too many for loops.
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
int main()
{
unsigned int i = 0;
int key[10];
unsigned int k = 0;
int check;
unsigned int j, jj, jjj, jjjj, jjjjj, jjjjjj;
int n = 50;
char slowo[10];
char plain[500], cipher[500];
fflush(stdin);
printf("Enter text:");
fgets(plain, 500, stdin);
printf("Enter word:");
fgets(slowo, 500, stdin);
if (strlen(slowo) == 4)
{
for (j = n; j != 0; j--)
{
key[0] = (j - 25);
for (jj = n; jj != 0; jj--)
{
key[1] = (jj - 25);
for (i = 0; i<strlen(plain); i++)
{
if (isalpha(plain[i]))
{
if (islower(plain[i]))
{
check = plain[i];
if (islower(plain[i]) && check + key[k]>96 && check + key[k]<123)
{
cipher[i] = (plain[i] + key[k] - 'a') % 26 + 'a';
}
else
{
check = 123 + (check - 97 + key[k]);
cipher[i] = (check - 'a') % 26 + 'a';
check = 0;
}
}
else
{
check = plain[i];
if (isupper(plain[i]) && check + key[k]>64 && check + key[k]<91)
{
cipher[i] = (plain[i] + key[k] - 'A') % 26 + 'A';
}
else
{
check = 91 + (check - 65 + key[k]);
cipher[i] = (check - 'A') % 26 + 'A';
check = 0;
}
}
}
else
if (isspace(plain[i]))
{
k--;
cipher[i] = plain[i];
}
k++;
if (k>strlen(slowo) - 3)//ostatniznak + \0
k = 0;
}
for (i = 0; i<strlen(plain); i++)
{
if (isspace(cipher[i]) && cipher[i + 1] == slowo[0] && cipher[i + 2] == slowo[1] && cipher[i + 3] == slowo[2] && isspace(cipher[i + 4]))
{
cipher[strlen(plain) - 1] = '\0';
printf("%s", cipher);
return 0;
}
}
}
}
}
if (strlen(slowo) == 5)
{
for (j = n; j != 0; j--)
{
key[0] = (j - 25);
for (jj = n; jj != 0; jj--)
{
key[1] = (jj - 25);
for (jjj = n; jjj != 0; jjj--)
{
key[2] = (jjj - 25);
for (i = 0; i<strlen(plain); i++)
{
if (isalpha(plain[i]))
{
if (islower(plain[i]))
{
check = plain[i];
if (islower(plain[i]) && check + key[k]>96 && check + key[k]<123)
{
cipher[i] = (plain[i] + key[k] - 'a') % 26 + 'a';
}
else
{
check = 123 + (check - 97 + key[k]);
cipher[i] = (check - 'a') % 26 + 'a';
check = 0;
}
}
else
{
check = plain[i];
if (isupper(plain[i]) && check + key[k]>64 && check + key[k]<91)
{
cipher[i] = (plain[i] + key[k] - 'A') % 26 + 'A';
}
else
{
check = 91 + (check - 65 + key[k]);
cipher[i] = (check - 'A') % 26 + 'A';
check = 0;
}
}
}
else
if (isspace(plain[i]))
{
k--;
cipher[i] = plain[i];
}
k++;
if (k>strlen(slowo) - 3)//ostatniznak + \0
k = 0;
}
for (i = 0; i<strlen(plain); i++)
{
if (isspace(cipher[i]) && cipher[i + 1] == slowo[0] && cipher[i + 2] == slowo[1] && cipher[i + 3] == slowo[2] && cipher[i + 4] == slowo[3] && isspace(cipher[i + 5]))
{
cipher[strlen(plain) - 1] = '\0';
printf("%s", cipher);
return 0;
}
}
}
}
}
}
if (strlen(slowo) == 6)
{
for (j = n; j != 0; j--)
{
key[0] = (j - 25);
for (jj = n; jj != 0; jj--)
{
key[1] = (jj - 25);
for (jjj = n; jjj != 0; jjj--)
{
key[2] = (jjj - 25);
for (jjjj = n; jjjj != 0; jjjj--)
{
key[3] = (jjjj - 25);
for (i = 0; i<strlen(plain); i++)
{
if (isalpha(plain[i]))
{
if (islower(plain[i]))
{
check = plain[i];
if (islower(plain[i]) && check + key[k]>96 && check + key[k]<123)
{
cipher[i] = (plain[i] + key[k] - 'a') % 26 + 'a';
}
else
{
check = 123 + (check - 97 + key[k]);
cipher[i] = (check - 'a') % 26 + 'a';
check = 0;
}
}
else
{
check = plain[i];
if (isupper(plain[i]) && check + key[k]>64 && check + key[k]<91)
{
cipher[i] = (plain[i] + key[k] - 'A') % 26 + 'A';
}
else
{
check = 91 + (check - 65 + key[k]);
cipher[i] = (check - 'A') % 26 + 'A';
check = 0;
}
}
}
else
if (isspace(plain[i]))
{
k--;
cipher[i] = plain[i];
}
k++;
if (k>strlen(slowo) - 3)//ostatniznak + \0
k = 0;
}
for (i = 0; i<strlen(plain); i++)
{
if (isspace(cipher[i]) && cipher[i + 1] == slowo[0] && cipher[i + 2] == slowo[1] && cipher[i + 3] == slowo[2] && cipher[i + 4] == slowo[3] && cipher[i + 5] == slowo[4] && isspace(cipher[i + 6]))
{
cipher[strlen(plain) - 1] = '\0';
printf("%s", cipher);
return 0;
}
}
}
}
}
}
}
if (strlen(slowo) == 7)
{
for (j = n; j != 0; j--)
{
key[0] = (j - 25);
for (jj = n; jj != 0; jj--)
{
key[1] = (jj - 25);
if (isspace(cipher[i]) && cipher[i + 1] == slowo[0] && cipher[i + 2] == slowo[1] && isspace(cipher[i + 7]))
{
jj--;
}
for (jjj = n; jjj != 0; jjj--)
{
key[2] = (jjj - 25);
for (jjjj = n; jjjj != 0; jjjj--)
{
key[3] = (jjjj - 25);
for (jjjjj = n; jjjjj != 0; jjjjj--)
{
key[4] = (jjjjj - 25);
for (i = 0; i<strlen(plain); i++)
{
if (isalpha(plain[i]))
{
if (islower(plain[i]))
{
check = plain[i];
if (islower(plain[i]) && check + key[k]>96 && check + key[k]<123)
{
cipher[i] = (plain[i] + key[k] - 'a') % 26 + 'a';
}
else
{
check = 123 + (check - 97 + key[k]);
cipher[i] = (check - 'a') % 26 + 'a';
check = 0;
}
}
else
{
check = plain[i];
if (isupper(plain[i]) && check + key[k]>64 && check + key[k]<91)
{
cipher[i] = (plain[i] + key[k] - 'A') % 26 + 'A';
}
else
{
check = 91 + (check - 65 + key[k]);
cipher[i] = (check - 'A') % 26 + 'A';
check = 0;
}
}
}
else
if (isspace(plain[i]))
{
k--;
cipher[i] = plain[i];
}
k++;
if (k>strlen(slowo) - 3)//ostatniznak + \0
k = 0;
}
for (i = 0; i<strlen(plain); i++)
{
if (isspace(cipher[i]) && cipher[i + 1] == slowo[0] && cipher[i + 2] == slowo[1] && cipher[i + 3] == slowo[2] && cipher[i + 4] == slowo[3] && cipher[i + 5] == slowo[4] && cipher[i + 6] == slowo[5] && isspace(cipher[i + 7]))
{
cipher[strlen(plain) - 1] = '\0';
printf("%s", cipher);
return 0;
}
}
}
}
}
}
}
}
if (strlen(slowo) == 8)
{
for (j = n; j != 0; j--)
{
key[0] = (j - 25);
for (jj = n; jj != 0; jj--)
{
key[1] = (jj - 25);
for (jjj = n; jjj != 0; jjj--)
{
key[2] = (jjj - 25);
for (jjjj = n; jjjj != 0; jjjj--)
{
key[3] = (jjjj - 25);
for (jjjjj = n; jjjjj != 0; jjjjj--)
{
key[4] = (jjjjj - 25);
for (jjjjjj = 0; jjjjjj != 0; jjjjjj--)
{
key[5] = (jjjjjj - 25);
for (i = 0; i<strlen(plain); i++)
{
if (isalpha(plain[i]))
{
if (islower(plain[i]))
{
check = plain[i];
if (islower(plain[i]) && check + key[k]>96 && check + key[k]<123)
{
cipher[i] = (plain[i] + key[k] - 'a') % 26 + 'a';
}
else
{
check = 123 + (check - 97 + key[k]);
cipher[i] = (check - 'a') % 26 + 'a';
check = 0;
}
}
else
{
check = plain[i];
if (isupper(plain[i]) && check + key[k]>64 && check + key[k]<91)
{
cipher[i] = (plain[i] + key[k] - 'A') % 26 + 'A';
}
else
{
check = 91 + (check - 65 + key[k]);
cipher[i] = (check - 'A') % 26 + 'A';
check = 0;
}
}
}
else
if (isspace(plain[i]))
{
k--;
cipher[i] = plain[i];
}
k++;
if (k>strlen(slowo) - 3)//ostatniznak + \0
k = 0;
}
for (i = 0; i<strlen(plain); i++)
{
if (isspace(cipher[i]) && cipher[i + 1] == slowo[0] && cipher[i + 2] == slowo[1] && cipher[i + 3] == slowo[2] && cipher[i + 4] == slowo[3] && cipher[i + 5] == slowo[4] && cipher[i + 6] == slowo[5] && cipher[i + 7] == slowo[6] && isspace(cipher[i + 7]))
{
cipher[strlen(plain) - 1] = '\0';
printf("%s", cipher);
return 0;
}
}
}
}
}
}
}
}
}
else {
printf("Error");
return 1;
}
}
I would like to optimize the code to make it faster, but I have no idea.

There are some possible optimizations - what is called a keyhole optimization - in your code, but I'd rather change the algorithm you're using. Keyhole optimizations are penny wise and pound foolish, and premature optimization is the root of all evil. Decreasing the algorithm complexity is almost always your top priority. Then and only then you do further optimizations.
Here you know that key length is (in the third example) five, because the crib effect is six characters; we'll refer to the key as 12345.
We align the key to the cyphertext since whitespaces are ignored:
12 345123 4512345 1 23451234 512 345123451 23 451 2345123
Rt kolniz qufkbnx R gjvoczkm zqk kgobzkwin ul cnn suwyckx
We could now implement a brute-force Babbage decryption in O(n3) using a linear equation system:
x1 - 1 = R
x2 - 2 = t
x3 - 3 = k
x4 - 4 = o
x5 - 5 = l
x6 - 1 = n
...
x48 - 3 = x
But we can rather observe that we only have one word whose length is equal to that of 'effect' - it is 'kolniz'. Which means that we can recover the key straight away: it is the difference "nikol - efeec". The first symbol, 1, equals to a shift forward from the second e of effect to the n of kolniz, that is, 9 positions. So when we find a letter mapped to the 1 symbol of the worm, such as the first 'R', we go back 9 positions from R, and we find 'I'.
The above algorithm is roughly O(n+m) with n being the length of the ciphertext and m being the length of the key.
Suppose we have two words whose length is equal to "effect", say they are "abcdef" and "ghijkl". Which one do we use?
Hypothesis 1: abcdef is the cyphertext of effect. If that is true then the shift for the first symbol of 'e' is 'a' and the same shift must get 'f' into 't'.
Hypothesis 2: ghikl is the cyphertext of effect. If that is true then the shift for the first symbol of 'e' is 'g' and the same shift must get 'l' into 't'.
The chances of both hypotheses being true and us not being able which one is correct are those of another word having the same shift difference in its first and last letters as are 'e' and 't' in our crib, for example the first word is 'effect' and the other is "cougar", "dirges", "harlow", or "jalopy". Those chances are very little.

Related

C - Recursion instead of loops

I made a program that evaluates expressions, for example
Enter text: 97+74/51-98-11+68-34-2-22+73/40+81/15+100
output :
105.36
If any wrong data is given a user gets a response Incorrect input
I am wondering if I could replace all my for loops to recursion, but I don't know how could I achieve that. Could anybody help ?
Any assistance would be much appreciated.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<math.h>
int my_atoi(const char* tab, int from, int to)
{
int score = 0;
int minus = 0;
for (int i = from; i <= to; i++)
{
if (*(tab + i) == 10)
break;
if (*(tab + i) == 32)
break;
if (*(tab + i) == '-' && from == i)
{
minus = 1;
continue;
}
if (*(tab + i) == '+' && i == from)
{
continue;
}
if (*(tab + i) > '9' || *(tab + i) < '0')
break;
else if (*(tab + i) >= '0' && *(tab + i) <= '9')
{
score *= 10;
score += (*(tab + i) - '0');
}
}
if (minus == 1)
score *= -1;
return score;
}
int validate_expression(const char* expr)
{
if (!expr)return -1;
int lng = strlen(expr) - 1;
if (*(expr) > '9' || *(expr) < '0' || * (expr + lng) > '9' || *(expr + lng) < '0')return 0;
int flaga = 0; // flag
for (int i = 1; i < lng; i++) {
if (*(expr + i) <= '9' && *(expr + i) >= '0')
{
flaga = 0;
}
else if (*(expr + i) == '/' || *(expr + i) == '*' || *(expr + i) == '-' || *(expr + i) == '+')
{
if (flaga == 1)
return 0;
flaga = 1;
}
else
return 0;
}
return 1;
}
int calculate(const char* expr, float* result)
{
if (!expr || !result || !validate_expression(expr)) return 0;
if (strpbrk(expr, "i") != NULL) return 0;
int index = 0;
float score = 0;
char sign_memory = 'A';
int flaga = 0;
unsigned int i = 1;
for (; i <= strlen(expr); i++) {
if (*(expr + i) == '-' || *(expr + i) == '+' || *(expr + i) == '/' || *(expr + i) == '*' || *(expr + i) == '\0') {
score += (int)my_atoi(expr, index, i - 1);
index = i;
break;
}
}
for (; i <= strlen(expr); i++) {
if (*(expr + i) == '-' || *(expr + i) == '+' || *(expr + i) == '/' || *(expr + i) == '*' || i == strlen(expr)) {
flaga = 1;
if (sign_memory == '+')
score += (int)my_atoi(expr, index, i - 1);
else if (sign_memory == '-')
score -= (int)my_atoi(expr, index, i - 1);
else if (sign_memory == '/')
{
if (my_atoi(expr, index, i - 1) == 0)return 0;
score /= (int)my_atoi(expr, index, i - 1);
}
else if (sign_memory == '*')
score *= (int)my_atoi(expr, index, i - 1);
sign_memory = *(expr + i);
}
else if (*(expr + i) <= '9' && *(expr + i) >= '0' && flaga == 1) {
flaga = 0;
index = i;
}
}
*result = score;
return 1;
}
int main()
{
char tab[201];
float result, * pointer = &result;
printf("Enter text: ");
fgets(tab, sizeof(tab), stdin);
*(tab + strlen(tab) - 1) = '\0';
if (!validate_expression(tab))
{
printf("Incorrect input");
return 1;
}
else
{
if (calculate(tab, pointer))
printf("%.2f", *pointer);
else {
printf("Incorrect input");
return 1;
}
}
return 0;
}
I would make a function, which does the following:
Check if there is just one or more operators ("+", "-", "*", "/")
In case there is only one, perform the calculation.
In case there are two, perform a tail recursion, as proposed by Jonathan, something like:
calculate("97+74/51-98-11+68-34-2-22+73/40+81/15+100")
= calculate("97+74/51-98-11+68-34-2-22+73/40+81/15") + 100
= (calculate("97+74/51-98-11+68-34-2-22+73/40+81") / 15) + 100
= ((calculate("97+74/51-98-11+68-34-2-22+73/40") + 81) / 15) + 100
= (((calculate("97+74/51-98-11+68-34-2-22+73") / 40) + 81) / 15) + 100
= ((((calculate("97+74/51-98-11+68-34-2-22") + 73) / 40) + 81) / 15) + 100
= (((((calculate("97+74/51-98-11+68-34-2") - 22) + 73) / 40) + 81) / 15) + 100
= ((((((calculate("97+74/51-98-11+68-34") - 2) - 22) + 73) / 40) + 81) / 15) + 100
= (((((((calculate("97+74/51-98-11+68") - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= ((((((((calculate("97+74/51-98-11") + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= (((((((((calculate("97+74/51-98") - 11) + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= ((((((((((calculate("97+74/51") - 98) - 11) + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= (((((((((((calculate("97+74") / 51) - 98) - 11) + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= ((((((((((((97 + 74) / 51) - 98) - 11) + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100

How to fix filling the struct with these data in c

I have struct input parameter and array of it called input_arr. I want to fill the array with the text as it gives the wrong value for the id and it work correctly with the name and nothing appear in visible.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct input_parameter {
int id;
char name[30];
int position;
char visible[5];
char required[5];
char parameter_type;
char client_id[5];
int min_length;
int max_length;
char confirm_required[5];
};
struct input_parameter input_arr[10];
char text[2*1024]="{\"success\": true,\"language\":
\"en\",\"action\":
\"GetServiceInputParameterList\",\"version\": 1,\"data\": {
\"input_parameter_list\": [{\"id\": 1489,\"service_id\":
12102,\"name\": \"Customer Number\",\"position\":
1,\"visible\":
true,\"required\": true,\"parameter_type\":
\"N\",\"client_id\":
true,\"min_length\": 11, \"max_length\":
11,\"confirm_required\":
false } ] }}";
Fill an array of structs with the text:
int main() {
int i = 0;
int Wstart = 0;
int Wend = 0;
char name[19] = {0x20};
char name1[19] = {0x20};
int menunum = 0;
int len = strlen(text);
while (1) // while ALL
{
if (i >= len) {
break;
}
if (text[i] == 'i' && text[i + 1] == 'd') {
while (1) { // while id
if (text[i] == ':') {
Wstart = i + 1;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i;
strncpy(name, text + Wstart, Wend - Wstart);
input_arr[menunum].id = atoi(name);
memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while id
} else if (text[i] == 'n' && text[i + 1] == 'a' && text[i + 2] == 'm' &&
text[i + 3] == 'e') {
while (1) { // while name
if (text[i] == ':') {
Wstart = i + 3;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i - 1;
strncpy(name, text + Wstart, Wend - Wstart);
// name[Wend-Wstart] = '\0';
// memset(name1, 0, sizeof(name1));
if ((name[1] >= 'a' && name[1] <= 'z') ||
(name[1] >= 'A' && name[1] <= 'Z')) {
// printf("%c is an alphabet.",c);
strcpy(name1, name);
} else {
int vc = 0;
int ia = strlen(name) - 1;
for (ia = strlen(name) - 1; ia >= 0; ia--) {
name1[vc] = name[ia];
vc++;
}
}
strcpy(input_arr[menunum].name, name1);
menunum++;
memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while name
} else if (text[i] == 'v' && text[i + 1] == 'i' && text[i + 2] == 's' &&
text[i + 3] == 'i' && text[i + 4] == 'b' &&
text[i + 5] == 'l' && text[i + 6] == 'e') {
while (1) { // while visible
if (text[i] == ':') {
Wstart = i + 3;
Wend = 0;
i++;
} else if (text[i] == ',' || text[i] == '}') {
Wend = i - 1;
strncpy(name, text + Wstart, Wend - Wstart);
// name[Wend-Wstart] = '\0';
memset(name1, 0, sizeof(name1));
if ((name[1] >= 'a' && name[1] <= 'z') ||
(name[1] >= 'A' && name[1] <= 'Z')) {
// printf("%c is an alphabet.",c);
strcpy(name1, name);
} else {
int vc = 0;
int ia = strlen(name) - 1;
for (ia = strlen(name) - 1; ia >= 0; ia--) {
name1[vc] = name[ia];
vc++;
}
}
strcpy(input_arr[menunum].visible, name1);
menunum++;
// memset(name, 0, sizeof(name));
i++;
break;
} else {
i = i + 1;
}
} // while visible
} else {
i++;
}
}
printf("id:%d \n name: %s \n visible: %s
\n",&input_arr[0].id,&input_arr[0].name,&input_arr[0].visible);
return 0;
}
Well you are printing address of id instead of its value using %d format specifier.
printf("id:%d\nname: %s\n visible: %d\n",&input_arr[0].id,&input_arr[0].name,&input_arr[0].visible);
should be
printf("id:%d \n name: %s \n visible: %d\n",input_arr[0].id,input_arr[0].name,input_arr[0].visible);

SetConsoleCursorPosition : Getting black rows in console upon use

Following my previous question about making a snake program more fluid, I went and tried ANSI escape sequences and console functions to put back the text cursor on the top left corner.
I want to get the cursor on the top left corner of the screen, but while it does so I get black stripes across the screen every other line.
I am working in a windows environment making this program for the windows console.
Here is the painting function :
void paint(int tab[28][120], int ligneMax, int colonneMax, HANDLE hconsole)
{
//system("cls");
//printf("\033[1;1H");
COORD destCoord;
destCoord.X = 0;
destCoord.Y = 0;
SetConsoleCursorPosition(hconsole, destCoord);
for (int i = 0; i < ligneMax; i++)
{
for (int j = 0; j < colonneMax; j++)
{
printf("%c", tab[i][j]);
}
printf("\n");
}
}
I tried putting the escape code and console function in the main right before calling the paint function but I got the same results.
here is the whole program if someone wants to test :
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>
void paint(int tab[28][120], int ligneMax, int colonneMax, HANDLE hconsole)
{
//system("cls");
//printf("\033[1;1H");
COORD destCoord;
destCoord.X = 0;
destCoord.Y = 0;
SetConsoleCursorPosition(hconsole, destCoord);
for (int i = 0; i < ligneMax; i++)
{
for (int j = 0; j < colonneMax; j++)
{
printf("%c", tab[i][j]);
}
printf("\n");
}
}
void create(int tab[28][120], int Nbligne, int Nbcolonne,
int randligne, int randcols)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
tab[i][j] = ' ';
if (i == 0 || i == Nbligne - 1)
tab[i][j] = 205;
if (j == 0 || j == Nbcolonne - 1)
tab[i][j] = 186;
if (i == 0 && j == 0)
tab[i][j] = 201;
if (i == 0 && j == Nbcolonne - 1)
tab[i][j] = 187;
if (i == Nbligne - 1 && j == 0)
tab[i][j] = 200;
if (i == Nbligne - 1 && j == Nbcolonne - 1)
tab[i][j] = 188;
if (i == 14 && j == 60)
tab[i][j] = 219;
if (i == 14 && j == 59)
tab[i][j] = 79;
if (i == 14 && j == 58)
tab[i][j] = 35;
if (i == randligne && j == randcols)
tab[i][j] = 176;
}
}
}
void destroyTail(int tab[28][120], int Nbligne, int Nbcolonne)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if (tab[i][j] == 35)
{
tab[i][j] = ' ';
if (tab[i][j + 1] == 79)
tab[i][j + 1] = 35;
else if (tab[i][j - 1] == 79)
tab[i][j - 1] = 35;
else if (tab[i + 1][j] == 79)
tab[i + 1][j] = 35;
else if (tab[i - 1][j] == 79)
tab[i - 1][j] = 35;
goto stop;
}
}
}
stop: NULL;
}
void translate(int tab[28][120], char direction, int Nbligne, int Nbcolonne)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if (tab[i][j] == 219)
{
if (direction == 'R')
{
tab[i][j] = 79;
tab[i][j + 1] = 219;
}
if (direction == 'D')
{
tab[i][j] = 79;
tab[i + 1][j] = 219;
}
if (direction == 'L')
{
tab[i][j] = 79;
tab[i][j - 1] = 219;
}
if (direction == 'U')
{
tab[i][j] = 79;
tab[i - 1][j] = 219;
}
goto stop;
}
}
}
stop: NULL;
}
int checkExpand(int tab[28][120], int Nbligne, int Nbcolonne, char direction)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if ((direction == 'R' && tab[i][j] == 219 && tab[i][j + 1] == 176) ||
(direction == 'L' && tab[i][j] == 219 && tab[i][j - 1] == 176) ||
(direction == 'U' && tab[i][j] == 219 && tab[i - 1][j] == 176) ||
(direction == 'D' && tab[i][j] == 219 && tab[i + 1][j] == 176))
return 1;
}
}
return 0;
}
int checkDeath(int tab[28][120], int Nbligne, int Nbcolonne, char direction)
{
for (int i = 0; i < Nbligne; i++)
{
for (int j = 0; j < Nbcolonne; j++)
{
if ((direction == 'R' && tab[i][j] == 219 && (tab[i][j + 1] == 186 || tab[i][j + 1] == 79)) ||
(direction == 'L' && tab[i][j] == 219 && (tab[i][j - 1] == 186 || tab[i][j - 1] == 79)) ||
(direction == 'U' && tab[i][j] == 219 && (tab[i - 1][j] == 205 || tab[i - 1][j] == 79)) ||
(direction == 'D' && tab[i][j] == 219 && (tab[i + 1][j] == 205 || tab[i + 1][j] == 79)))
return 1;
}
}
return 0;
}
int main()
{
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 241);
int tab[28][120];
int randligne = rand() % 26 + 1;
int randcols = rand() % 118 + 1;
create(tab, 28, 120, randligne, randcols);
paint(tab, 28, 120, hConsole);
char i = '1';
char direction = 'R';
int eaten = 0;
int expand = 0;
int death = 0;
while(i != 'k')
{
if (kbhit())
i = getch();
switch(i) {
case 'z':
if (direction != 'D')
direction = 'U';
break;
case 's':
if (direction != 'U')
direction = 'D';
break;
case 'd':
if (direction != 'L')
direction = 'R';
break;
case 'q':
if (direction != 'R')
direction = 'L';
break;
}
randligne = rand() % 26 + 1;
randcols = rand() % 118 + 1;
death = checkDeath(tab, 28, 120, direction);
if (death == 1)
break;
translate(tab, direction, 28, 120);
expand = checkExpand(tab, 28, 120, direction);
if (expand == 0)
destroyTail(tab, 28, 120);
else
{
while (tab[randligne][randcols] != ' ')
{
randligne = rand() % 26 + 1;
randcols = rand() % 118 + 1;
}
tab[randligne][randcols] = 176;
eaten++;
}
printf("Number of biscuits eaten : %d ; direction : %c ; expand : %d", eaten, direction, expand);
paint(tab, 28, 120, hConsole);
Sleep(100);
}
while(i != 'k')
{
if (kbhit())
i = getch();
}
}
Too much code to take in quickly. If you have Windows console ouput for the snake, can't you simply printf the next line and leave it at that?
If you want to hide the cursor (instead of trying to park it out of sight) you can make it invisible by calling SetConsoleCursorInfo and the struct passed is shown here.

Converting 2D array of numbers into chars

I am making a maze using Depth-First search algorithm as a school project. The maze is working pretty much as I want but I have a little problem. I have to use # as a wall and . as a path when printing the maze but I used 0 as a wall and 1 as a path at first thinking that it is gonna be easy to change it later but I was wrong. How can I change 0 and 1 into # and .?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void nahodne_suradnice(int *r, int *s, int n)
{
srand(time(NULL));
*r = ((rand() % n) - 1) + 2;
if (*r == 1 || *r == n)
{
*s = (rand() % n) + 2;
}
else
{
if (rand() % 2 == 1)
*s = 1;
else
*s = n;
}
}
int main()
{
int i, j, n, r, s,smer,posledny_smer[1500];
int maze[500][500];
scanf_s("%d", &n);
if (n < 10 || n > 100)
{
return 0;
}
//vynulovanie pola/bludiska
for (i = 1; i < n + 1; i++)
{
for (j = 1; j < n + 1; j++)
{
maze[i][j] = 0;
}
}
//nahodny vyber zaciatku bludiska
nahodne_suradnice(&r, &s, n);
//generovanie bludiska
j = 0;
maze[r][s] = 2;
for (i = 0 ;; i++)
{
//backtracking
if ((maze[r - 1][s] == 1 || maze[r - 2][s] == 1 || r - 2 <=1 || s==n || s==1) && (maze[r][s + 1] == 1 || maze[r][s + 2] == 1 || s + 2 >= n || r == n || r==1) && (maze[r + 1][s] == 1 || maze[r + 2][s] == 1 || r + 2 >= n || s == n || s==1) && (maze[r][s - 1] == 1 || maze[r][s - 2] == 1 || s - 2 <=1 || r == n || r==1))
{
if (posledny_smer[j-1] == 1)
if (maze[r + 1][s] == 1 && maze[r + 2][s] == 1)
{
r += 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 2)
if (maze[r][s - 1] == 1 && maze[r][s - 2] == 1)
{
s -= 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 3)
if (maze[r - 1][s] == 1 && maze[r - 2][s] == 1)
{
r -= 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (posledny_smer[j-1] == 4)
if (maze[r][s + 1] == 1 && maze[r][s + 2] == 1)
{
s += 2;
j--;
continue;
}
else
{
j--;
continue;
}
if (j == 0)
{
if (r == n)
{
nahodne_suradnice(&r, &s,n);
maze[1][s] = 3;
maze[2][s] = 3;
}
if (r == 1)
{
nahodne_suradnice(&r, &s, n);
maze[n][s] = 3;
maze[n - 1][s] = 3;
}
if (s == n-2)
{
nahodne_suradnice(&r, &s, n);
maze[r][1] = 3;
maze[r][2] = 3;
}
if (s == 3)
{
nahodne_suradnice(&r, &s, n);
maze[r][n] = 3;
maze[r][n-1] = 3;
}
break;
}
}
//buranie stien
smer = (rand() % 4) + 1;
if (smer == 1)
{
if (r - 2 >1 && s<n && s>1)
{
if (maze[r - 1][s] == 1 || maze[r - 2][s] == 1)
continue;
maze[r - 1][s] = 1;
maze[r - 2][s] = 1;
r -= 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 2)
{
if (s + 2 < n && r < n && r>1)
{
if (maze[r][s+1] == 1 || maze[r][s+2] == 1)
continue;
maze[r][s + 1] = 1;
maze[r][s + 2] = 1;
s += 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 3)
{
if (r + 2 < n && s < n && s>1)
{
if (maze[r + 1][s] == 1 || maze[r + 2][s] == 1)
continue;
maze[r + 1][s] = 1;
maze[r + 2][s] = 1;
r += 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
if (smer == 4)
{
if (s - 2 >1 && r < n && r>1)
{
if (maze[r][s-1] == 1 || maze[r][s-2] == 1)
continue;
maze[r][s - 1] = 1;
maze[r][s - 2] = 1;
s -= 2;
posledny_smer[j] = smer;
j++;
continue;
}
}
}
//vypis bludiska
for (i = 1; i < n + 1; i++)
{
for (j = 1; j < n + 1; j++)
{
printf("%d", maze[i][j]);
}
printf("\n");
}
system("PAUSE");
return 0;
}
`
Thanks.
Change the definition of maze to:
char maze[500][500]
and change all references to use char instead of int. Then return '#' and '.' instead of 0 and 1.
You can change from 0 and 1 to # and . (or any other representation) when printing. For instance you can change:
printf("%d", maze[i][j]);
to
switch(maze[i][j]) {
case 0:
printf("#");
break;
case 1:
printf(".");
break;
default:
printf("X"); /* in case you have some value other than 0 or 1 in the maze */
}
If you do it like this, you can change which letters you want to display the maze as without changing other parts of your code.

Arrays in C and Prime Numbers

I need help with my programming assignment, I have everything done except for one part! Here is the assignment:
Problem 1: String Operations and Data Security: To improve data security in the transmission of data and information, dynamic character coding is being practiced. The modification of the original characters can be using the first 8 prime members [1, 2, 3, 5, 7, 11, 13, 17]: First character enhanced by 1; second character by 2, third by 3, .. 8th character by 17. Next 8 characters use the prime numbers in the reverse order 17..1, and decrease the values. Use a total message of at least 64 characters [in quantities of 8 characters] and repeat the process of modifying 1-17 for the first 8; modifying by 17 -1 for next 8, and so on. Make your own message. After the message is coded, decoding should also be done, to restore the original message. You may want to change the lower case and upper case transitions as well.
Example: Original Message A B C D. …..
Normal ASCII 65 66 67 68 ….
Prime Numbers 1 2 3 5 ….
Enhanced ASCII 66 68 70 73 ….
Coded Message B D F I ……
I'm having trouble printing out the prime numbers without messing up the code afterwards such as the encoded and decoded ASCII codes and the encoded and decoded codes. This is my code so far:
If you could help me somehow that would be great! I would really appreciate it, thank you.
size_t x;
int i, c;
i = 1;
c = 0;
char text[65];
int s[8] = {1, 2, 3, 5, 7, 11, 13, 17};
printf("Enter a line of text: "); // prompts user to enter text
fgets(text, 65, stdin); // reads input from user
printf("\nOriginal Message: ");
for(x = 0; x < strlen(text); ++x) // for loop to print original message
{
printf("%c", text[x]);
} // end for
// ASCII Code
printf("\nASCII Code: ");
for(x = 0; x < strlen(text) - 1; ++x)
{
printf("%d ", text[x]);
}
// prime numbers
// my issue is here
printf("\n\nPrime Numbers: ");
for(x = 0; x <= 8 ; ++x)
{
if(c == 0)
{
if(i == 1)
{
printf("1 ");
++i;
}
else if(i == 2)
{
printf("2 ");
++i;
}
else if(i == 3)
{
printf("3 ");
++i;
}
else if(i == 4)
{
printf("5 ");
++i;
}
else if(i == 5)
{
printf("7 ");
++i;
}
else if(i == 6)
{
printf("11 ");
++i;
}
else if(i == 7)
{
printf("13 ");
++i;
}
else if(i == 8)
{
printf("17 ");
++c;
++x;
}
}
if(c == 1)
{
if(i == 8)
{
printf("17 ");
--i;
}
else if(i == 7)
{
printf("13 ");
--i;
}
else if(i == 6)
{
printf("11 ");
--i;
}
else if(i == 5)
{
printf("7 ");
--i;
}
else if(i == 4)
{
printf("5 ");
--i;
}
else if(i == 3)
{
printf("3 ");
--i;
}
else if(i == 2)
{
printf("2 ");
--i;
}
else if(i == 1)
{
printf("1 ");
--c;
}
} // end outer if
} // issue ends here
for(x = 0; x < strlen(text) - 1; ++x)
{
if(c == 0) // outer if statement increasing
{
if(i == 1) // inner if statement
{
text[x] = text[x] + 1;
++i;
}
else if (i == 2)
{
text[x] = text[x] + 2;
++i;
}
else if (i == 3)
{
text[x] = text[x] + 3;
++i;
}
else if(i == 4)
{
text[x] = text[x] + 5;
++i;
}
else if(i == 5)
{
text[x] = text[x] + 7;
++i;
}
else if(i == 6)
{
text[x] = text[x] + 11;
++i;
}
else if(i == 7)
{
text[x] = text[x] + 13;
++i;
}
else if(i == 8)
{
text[x] = text[x] + 17;
++c;
++x;
} // end if statement
} // end outer if statement
if(c == 1) // outer if statement decreasing
{
if(i == 8)
{
text[x] = text[x] + 17;
--i;
}
else if(i == 7)
{
text[x] = text[x] + 13;
--i;
}
else if(i == 6)
{
text[x] = text[x] + 11;
--i;
}
else if(i == 5)
{
text[x] = text[x] + 7;
--i;
}
else if(i == 4)
{
text[x] = text[x] + 5;
--i;
}
else if(i == 3)
{
text[x] = text[x] + 3;
--i;
}
else if(i == 2)
{
text[x] = text[x] + 2;
--i;
}
else if(i == 1)
{
text[x] = text[x] + 1;
--c;
}
} // end outer if
} // end for
printf("\n\nEncrypted Message: ");
for(x = 0; x <= strlen(text) - 1; ++x)
{
printf("%c", text[x]);
}
printf("\nEncrypted ASCII: ");
for(x = 0; x < strlen(text) - 1; x++)
{
printf("%d ", text[x]);
}
c = 0;
i = 1;
for(x = 0; x < strlen(text) - 1; ++x)
{
if(c == 0)
{
if(i == 1)
{
text[x] = text[x] - 1;
++i;
}
else if(i == 2)
{
text[x] = text[x] - 2;
++i;
}
else if(i == 3)
{
text[x] = text[x] - 3;
++i;
}
else if(i == 4)
{
text[x] = text[x] - 5;
++i;
}
else if(i == 5)
{
text[x] = text[x] - 7;
++i;
}
else if(i == 6)
{
text[x] = text[x] - 11;
++i;
}
else if(i == 7)
{
text[x] = text[x] - 13;
++i;
}
else if(i == 8)
{
text[x] = text[x] - 17;
++c;
++x;
} // end if statement
} // end outer if statement
if(c == 1)
{
if(i == 8)
{
text[x] = text[x] - 17;
--i;
}
else if(i == 7)
{
text[x] = text[x] - 13;
--i;
}
else if(i == 6)
{
text[x] = text[x] - 11;
--i;
}
else if(i == 5)
{
text[x] = text[x] - 7;
--i;
}
else if(i == 4)
{
text[x] = text[x] - 5;
--i;
}
else if(i == 3)
{
text[x] = text[x] - 3;
--i;
}
else if(i == 2)
{
text[x] = text[x] - 2;
--i;
}
else if(i == 1)
{
text[x] = text[x] - 1;
--c;
} // end inner if statements
} // end outer if statements
} // end for
printf("\n\nDecrypted Message: ");
for(x = 0; x < strlen(text); ++x)
{
printf("%c", text[x]);
}
printf("\nDecrypted ASCII: ");
for(x = 0; x < strlen(text) - 1; ++x)
{
printf("%d ", text[x]);
}
puts(" ");
} // end main
Characters are represented by numbers. For example, for ASCII, z is represented by the number 122. If you add something to that value then you get a new value (e.g. 122 + 17 = 139). That new value may not be valid ASCII (e.g. 128 or larger), and might be a control code (e.g. 127 is the "delete" control character).
Because the values may no longer represent valid characters, you can't print them as characters. You need to print them as values (e.g. for(x = 0; text[x] != 0; x++) { printf("%d ", text[x]); }).
Worse, for "signed char", the addition can cause overflow, which is undefined behaviour in C. You'd need to use a different data type (e.g. unsigned char or uint8_t) to ensure the code has defined/expected behaviour.
Also note that your long chain of "if .. else if ... else if" statements should be a "switch()" with cases; more like this:
switch(i) {
case 1:
text[x] = text[x] + 1;
++i;
break;
case 2:
text[x] = text[x] + 2;
++i;
break;
...
}
However; by using int s[16] = {1, 2, 3, 5, 7, 11, 13, 17, 17, 13, 11, 7, 5, 3, 2, 1}; you'd be able replace many lines of similar code with something like this:
for(x = 0; text[x] != 0; x++) {
text[x] += s[x % 16]);
}

Resources