Encryption Program Swapping? - c

I was planning on creating an encryption program. Basically swap anything that is from the normal "abcdefghijklmnopqrstuvwxyz" to ""thequickbrownfxjmpsvlazydg".
For example, If I were to key in. "abc" it would result as "the".
#include <stdio.h>
#include <string.h>
void encrypt(char *text, char *map);
void decrypt(char *text, char *map);
int main()
{
char a[] = {'a','b','c','d','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char b[] = {'t','h','e','q','u','i','c','k','b','r','o','w','n','f','x','j','m','p','s','v','l','a','z','y','d','g'};
char *textptr;
char *mapptr;
textptr = a;
mapptr = b;
encrypt(textptr, mapptr);
return 0;
}
void encrypt(char *text, char *map)
{
char string[100];
int len;
int x = 0, y = 0, l = 1;
printf("Please enter the string: ");
scanf("%s", string);
len = strlen(string);
for (x = 0; x < len; x++)
{
for (y = 0; y < 26; y++)
{
if(text[x] == map[y])
text[x] = map[y];
}
}
printf("The Ciphertext is: %s", string);
}
and the output is the same plain text that was inputted.. can you guys help me on this?

Your problem lies here:
strcpy (string[q],map[r]);
You're passing two chars to strcpy() instead of char *. To replace a single character, just do
string[q] = map[r];
Edit: the new code
if(text[x] == map[y])
text[x] = map[y];
That obviously changes nothing. It should be
if( string[x] == text[y] )
string[x] = map[y];

This is the problem:
if(text[x] == map[y])
text[x] = map[y];
Use:
if(string[x] == text[y])
string[x] = map[y];

you can do this by using simply single for loop. and you need to define array a[].
for (x = 0; x < strlen(string); x++)
{
string[x]=map[string[x]-'a'];
}
Modified code:
#include <stdio.h>
#include <string.h>
#include<ctype.h>
void encrypt(char *map);
int main()
{
char b[] = {'t','h','e','q','u','i','c','k','b','r','o','w','n','f','x','j','m','p','s','v','l','a','z','y','d','g'};
char *mapptr;
mapptr = b;
encrypt(mapptr);
return 0;
}
void encrypt(char *map)
{
char string[100];
int x = 0;
printf("Please enter the string: ");
scanf("%s", string);
for (x = 0; x < strlen(string); x++)
{
if(islower(string[x]))
string[x]=map[string[x]-'a'];
}
printf("The Ciphertext is: %s\n", string);
}

Related

Need to sort a string input by the most frequent characters first in C (qsort)

I managed to sort it alphabetically but I need to sort it by the most frequent characters first after that. Since I'm new to C programming Im not sure if this alphabetical sort is needed. Also I thought about using a struct but not sure how to do the whole process with it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmpfunc(const void *a, const void *b) {
return *(char*)a - *(char*)b;
}
void AlphabetOrder(char str[]) {
qsort(str, (size_t) strlen(str), (size_t) sizeof(char), cmpfunc);
printf("%s\n", str);
}
void Max_Occurring(char *str)
{
int i;
int max = 0;
int freq[256] = {0};
for(i = 0; str[i] != '\0'; i++)
{
freq[str[i]] = freq[str[i]] + 1;
}
for(i = 0; i < 256; i++)
{
if(freq[i] > freq[max])
{
max = i;
}
}
printf("Character '%c' appears %d times", max, freq[max], str);
}
int main() {
char str1[20];
printf("Enter a string: ");
scanf("%s", &str1);
AlphabetOrder(str1);
Max_Occurring(str1);
return 0;
}
I wrote you a frequency sorter using the idea that #WeatherVane mentioned:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct cfreq {
unsigned char c;
int freq;
};
int freqcmp(const void *a, const void *b) {
struct cfreq *a2 = (struct cfreq *) a;
struct cfreq *b2 = (struct cfreq *) b;
if(a2->freq < b2->freq) return -1;
if(a2->freq == b2->freq) return 0;
return 1;
}
int freqcmpdesc(const void *a, const void *b) {
return -freqcmp(a, b);
}
void FrequencyOrder(const char str[]) {
struct cfreq cfreqs[256];
for(int i = 0; i < sizeof(cfreqs) / sizeof(*cfreqs); i++) {
cfreqs[i].c = i;
cfreqs[i].freq = 0;
}
for(int i = 0; str[i]; i++) cfreqs[str[i]].freq++;
qsort(cfreqs, sizeof(cfreqs) / sizeof(*cfreqs), sizeof(*cfreqs), freqcmpdesc);
for(int i = 0; i < sizeof(cfreqs) / sizeof(*cfreqs); i++) {
if(cfreqs[i].freq) printf("%c", cfreqs[i].c);
}
printf("\n");
}
int main() {
char str1[20];
printf("Enter a string: ");
scanf("%s", &str1);
FrequencyOrder(str1);
return 0;
}
and here is a sample session (note: output is not deterministic for letters with same frequency):
Enter a string: buzz
zbu
If you want duplicate letters in the output then replace the print with a loop along these lines:
while(cfreqs[i].freq--) printf("%c", cfreqs[i].c);
Im not sure if this alphabetical sort is needed.
It is not needed, yet if done, Max_Occurring() can take advantage of a sorted string.
Since the string is sorted before calling Max_Occurring(), compute the max occurring via a count of adjacent repetitions of each char.
// Untested illustrative code.
// str points to a sorted string.
void Max_Occurring(const char *str) {
char max_ch = '\0';
size_t max_occurence = 0;
char previous = '\0';
size_t occurrence = 0;
while (*str) {
if (*str == previous) {
occurrence++;
} else {
occurrence = 1;
}
if (occurrence > max_occurence) {
max_occurence = occurrence;
max_ch = *str;
}
previous = *str;
str++;
}
printf("Character '%c' appears %zu times", max_ch, max_occurence);
}
In the case of multiple characters with the same max occurrence, this code only reports one max.
Avoid buffer overflow
Do not use scanf("%s"... without a width limit.
Tip: enable all warnings to save time and see the problem of using &str1 when str1 should be used.
char str1[20];
...
// scanf("%s", &str1);
scanf("%19s", str1);
Avoid a negative index
If still wanting to for a frequency table, watch out for the case when char is signed and code use str[i] < 0 to index an array.
Instead:
const unsigned char *ustr = (const unsigned char *) str;
size_t freq[UCHAR_MAX + 1] = {0};
for(size_t i = 0; ustr[i] != '\0'; i++) {
freq[ustr[i]]++;
}
Here's another alternative that may be simpler.
void freqOrder( char *p ) {
#define ASCIIcnt 128 // 7bit ASCII
// to count occurences of each character
int occur[ ASCIIcnt ];
memset( occur, 0, sizeof occur );
int maxCnt = 0; // remember the highest count
// do the counting
for( ; *p; p++ )
if( ++occur[ *p ] > maxCnt )
maxCnt = occur[ *p ];
// output most frequent to least frequen
for( ; maxCnt; maxCnt-- )
for( int i = 0; i < ASCIIcnt; i++ )
if( occur[i] == maxCnt )
while( occur[i]-- )
putchar( i );
putchar( '\n' );
}
int main( void ) {
freqOrder( "The quick brown fox jumps over the lazy dog" );
return 0;
}
Output
' ooooeeehhrruuTabcdfgijklmnpqstvwxyz'

separate numbers and string into text and numbers

I am trying to write code where I can separate string and numbers.
The string I have to separate it completely already the numbers I have to separate every 2 numbers.
My Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void getString(const char *str) {
char nums[50];
char alphas[50];
for (int i = 0; i < strlen(str); i++) {
if (isdigit(str[i]))
strcpy(nums, str);
if (isalpha(str[i]))
strcpy(alphas, str);
}
printf("str: %s\n", alphas);
printf("num: %d\n", atoi(nums));
}
int main() {
char *str = "one01two02three03";
getString(str);
return 0;
}
What I'm trying to do should return me as follows
str: onetwothree
num1: 01
num2: 02
num3: 03
The following parses the input and produces the correct output.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int *nums = NULL;
int num_count = 0;
char save_num(int n)
{
nums = realloc(nums, sizeof(int)*(num_count+1));
nums[num_count++] = n;
return '\0';
}
void getString(const char *str)
{
char* alpha = malloc(strlen(str)+1);
char* num = malloc(strlen(str)+1);
size_t i;
alpha[0] = '\0';
num[0] = '\0';
for (i = 0; i < strlen(str); i++)
{
if (isdigit(str[i]))
strncat(num, str+i, 1);
else if(isalpha(str[i]))
{
strncat(alpha, str+i, 1);
if(strlen(num) > 0)
num[0] = save_num(atoi(num));
}
}
if(strlen(num) > 0)
save_num(atoi(num));
printf("str: %s\n", alpha);
for(i = 0 ; i < num_count ; ++i)
printf("num%Zu: %02d\n", i+1, nums[i]);
free(alpha);
free(num);
}
int main()
{
char *str = "one01two02three03";
getString(str);
return 0;
}
This provides what you have asked for:
void getString(const char *str)
{
char one[10],two[10],three[10];
int x,y,z;
char a[10],b[10],c[10];
sscanf(str,"%[^0-9]""%[0-9]""%[^0-9]""%[0-9]""%[^0-9]""%[0-9]",a,one,b,two,c,three);
x = atoi(one);
y = atoi(two);
z = atoi(three);
printf("str: %s%s%s\n",a,b,c);
printf("num: %d\n",x);
printf("num: %d\n",y);
printf("num: %d\n",z);
}
Don´t forget to provide the declaration of getString before main():
void getString(const char *str);
So all together:
#include <stdio.h>
void getString(const char *str);
int main()
{
char *str = "one01two02three03";
getString(str);
return 0;
}
void getString(const char *str)
{
char one[10],two[10],three[10];
int x,y,z;
char a[10],b[10],c[10];
sscanf(str,"%[^0-9]""%[0-9]""%[^0-9]""%[0-9]""%[^0-9]""%[0-9]",a,one,b,two,c,three);
x = atoi(one);
y = atoi(two);
z = atoi(three);
printf("str: %s%s%s\n",a,b,c);
printf("num: %d\n",x);
printf("num: %d\n",y);
printf("num: %d\n",z);
}
Output:
str: onetwothree
num: 01
num: 02
num: 03
Since you have already set your strings 'nums' and 'alphas' there is no need to handle them dynamically.You should just copy the elements of the array str,one by one, to either the array num or the array alphas.
To distinguish different numbers just put a special character between numbers in the num array.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void getString(const char *str)
{
char nums[50];
char alphas[50];
int digits = 0;
int alpha = 0;
for (int i = 0; i < strlen(str); i++) {
if (isdigit(str[i])){
while(isdigit(str[i])){
nums[digits] = str[i];
i++;
digits++;
}
nums[digits]='\n';
digits++;
}
if(isalpha(str[i])){
alphas[alpha] = str[i];
alpha++;
}
}
printf("str: %s\n", alphas);
int n,p=0;
char subbuf[5];
for(n=0;n<digits;n++){
p=n;
while(nums[n]!='\n'){
n++;
}
memcpy(subbuf,&nums[p],n-p);
printf("num: %d\n", atoi(subbuf));
}
}
int main()
{
char *str = "01two02three03";
getString(str);
return 0;
}
Be aware that strcpy sets the pointer of the first argument to point to the second argument,this means that when you write strcpy(nums,str) in your code above, you copy the entire str string to the num several times.
Using an array for this question is not necessary, unless the array is to be used later. So my answer to this question is short and simple:
#include <stdio.h>
#include <stdbool.h>
void getString(const char *str)
{
bool in_number = false;
while (*str) {
if (*str >= '0' && *str <= '9') {
if (!in_number) { // Transition from a non-digit to digit
printf(": ");
in_number = true;
}
} else if (in_number) { // Transition from a digit to non-digit
putchar('\n');
in_number = false;
}
putchar(*str++);
}
putchar('\n');
}
int main(void)
{
char *str = "one01two02three03";
getString(str);
return 0;
}
The boolean variable in_number is used to catch the transitions from a digit character to a non-digit character and from a non-digit character to a digit character.

How to divide a string to substring and assign another substring?

I want to divide *eString to substrings. Substrings should be like that:
y_{1} = y_{1}y_{m+1}y_{2m+1}...
y_{2} = y_{2}y_{m+2}y_{2m+2}...
y_{m} = y_{m}y_{2m}y_{3m}...
where y is the element of *eString, and y is the substring of these elements.
For instance, if an user expects the key length which is 5, there should be (string size / 5) substrings. y_{1} has to contain the fist element of each divided substring. So, how can I implement this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ALPHA 26
char *ReadFile(char *);
int main(int argc, char *argv[])
{
double frequency[ALPHA] = {0};
int c = 0;
int keylen = 0;
int counter = 0;
double indexofCoincidence = 0,total = 0;
const char *eString = ReadFile("cipher.txt");
int len = 0;
if (eString) {
puts("The encrypted text is:");
puts(eString);
puts("");
len = strlen(eString);
printf("The length of text is %d\n",len);
}
puts("");
while(eString[c]!= '\0'){
if(eString[c]>= 'a' && eString[c]<='z')
frequency[eString[c]-'a']++;
c++;
}
puts("The letters frequencies are :\n");
for(c=0; c<ALPHA;c++){
if(frequency[c]!= 0)
printf("%c : %.3f\t",c+'a',(frequency[c]/len));
total += (frequency[c]*(frequency[c]-1));
}
indexofCoincidence = (total/((len)*(len-1)));
printf("\n\nIndex of Coincidence : %.3f\n",indexofCoincidence);
if(indexofCoincidence < 0.060){
printf("\nIt looks like randomly.\n");
}
printf("Enter the your expected key length : ");
scanf("%d",keylen);
printf("\n");
char *y;
while(counter != keylen)
{
for(int i = 0; i<(len/keylen);i++){
y[counter] = *eString();
}
counter++
}
return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char *eString = "The quick brown fox jumps over the lazy dog";
int keylen = 5;
int len = strlen(eString);
int y_len = (len + keylen) / keylen + 1;
int i,j;
char **y = malloc(keylen * sizeof(*y));
for(i=0; i < keylen; ++i){
y[i] = malloc(y_len * sizeof(**y));
}
char *p = eString;
i = j = 0;
while(*p){
y[i % keylen][j] = *p++;
y[i % keylen][j+1] = 0;
if(++i % keylen == 0)
++j;
}
//check print & deallocate
for(i = 0; i < keylen; ++i){
printf("y_{%d} : %s\n", i+1, y[i]);
free(y[i]);
}
free(y);
return 0;
}

Splitting string into strings of certain size in C

Let's say I have a string "abcd1234efgh". I want to split it into substrings of length 4, like:
abcd
1234
efgh
My C is rusty. Here's what I wrote:
#include<stdio.h>
#include<string.h>
int main(void){
int i,j;
char values[32]="abcd1234efgh";
char temp[10];
for(i=0;values[i]!='\0';){
for (j=0;j<4;j++,i++){
temp[i]=values[j];
printf("%c\n",values[j]);
}
printf("string temp:%s\n",temp);
}
return 0;
}
The output is obviously wrong because I'm not saving the index of the original string. Any tips on how to fix this? For strings with a length that is not a multiple of 4, I would like to pad the short substring with spaces.
This should do the trick if you're seeking to print only:
int len = strlen(values);
for (int off = 0; off < len; off += 4)
printf("%.4s\n", values+off);
If you want to do something else (as well) with the groups of 4, then I'd consider:
int len = strlen(values);
for (int off = 0; off < len; off += 4)
{
strncpy(temp, values+off, 4);
temp[4] = '\0';
…do as you will with temp…
}
NOTE : the code is to print in group of 4 and not break and store the string if size 4
if this is what you asked for
#include<stdio.h>
#include<string.h>
int main(void)
{
int i;
char values[32]="abcd1234efgh";
for(i=0;values[i]!='\0';)
{
if( i % 4 == 0 ) printf("\n");
printf("%c",values[i]);
}
return 0;
}
This should do the trick
#include <stdio.h>
#include <string.h>
int main() {
char *str = "abcd1234efgh";
size_t sub_len = 4;
size_t len = strlen(str);
size_t n = len / sub_len;
if(n * sub_len < len)
n += 1;
char temp[n][sub_len+1];
int i;
for (i = 0; i < n; ++i){
strncpy(temp[i], str + i*sub_len, sub_len);
temp[i][sub_len]='\0';
printf("string temp:%s\n", temp[i]);
}
return 0;
}
#include<stdio.h>
#include<string.h>
int main(void){
int i,j;
char values[32]="abcd1234efgh12";
char temp[10];
for(i=0;values[i]!='\0';){
for (j=0;j<4;j++,i++){
temp[j]=values[i];
}
while(j<4)
{
temp[j]=' ';
}
temp[j]='\0';
printf("string temp:%s\n",temp);
}
return 0;
}

string reverse program in C

i have written a program to reverse a string.. But it is not working.. It is printing the same string which is scanned.. What is the problem with the code?
#include <stdio.h>
#include <stdlib.h>
char *strrev(char *s)
{
char *temp = s;
char *result = s;
char t;
int l = 0, i;
while (*temp) {
l++;
temp++;
}
temp--;
for (i = 0; i < l; i++) {
t = *temp;
*temp = *s;
*s = t;
s++;
temp--;
}
return result;
}
int main()
{
char *str;
str = malloc(50);
printf("Enter a string: ");
scanf("%s", str);
printf("%s\n\n", strrev(str));
return 0;
}
for (i = 0; i < l; i++)
You're walking through the entire string, so you're reversing it twice - it won't be reversed after all. Walk only halfways:
for (i = 0; i < l / 2; i++)
Also, try using int len = strlen() instead of the while-not-end-of-string loop, if you're permitted to do so.
You swap the string's content twice.
Use the following code ..
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
char *strrev(char *s)
{
char *temp = s;
char *result = s;
char t;
while (*temp)
temp++;
while (--temp != s)
{
t = *temp;
*temp = *s;
*s++ = t;
}
return result;
}
int main()
{
char *str;
str = (char*)malloc(50);
printf("Enter a string: ");
scanf("%s", str);
printf("%s\n\n", strrev(str));
return 0;
}
The logic is to swap characters from start upto first half with the characters from last of second half, i.e, upto len/2. Just modify your for loop as below & it will work fine for you
for (i = 0; i < l/2; i++) {
you can use this simple code
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int str_len (char *str)
{
char *ptr = str;
while (*str)
str++;
return str - ptr;
}
int main ()
{
char *str;
int length;
str = (char*)malloc(50);
printf("Enter a string: ");
scanf("%s", str);
length = str_len(str) - 1;
for (int i = length ; i >= 0 ; i--)
printf ("%c", str[i]);
return 0;
}
you can use this code to reverse the string
#include<stdio.h>
#include<string.h>
int main()
{
int n,i;
char str2[100],str1[100];
printf("enter teh string 1\n");
gets(str1);
n = strlen(str1);
for(i=0;i<n;i++)
{
str2[n-1-i]=str1[i];
}
printf("%s\n",str2);
}
Actually you are reversing the string twice...so after come to middle of the string, you should terminate the loop that is your loop should be run for half of the string length that is l/2 (in this case). so your loop should be like
for(i = 0; i < i / 2; i++)
swapping the string content twice..
swapping it once will help..
for (i = 0; i < l/2; i++)

Resources