After putting two strings, it returns me
segmention fault (core dumbed)
I'm running the code with gcc. Valgrind writes that there are no errors. Tried to write code that decrypts text using the Caesar method. First I enter the text to be decoded, and the second text shows how far I need to move the letters in the first text. That is, the distance is selected at which there is more correspondence in letters between the received text and the second entered text. I carefully checked everything, for me it seems that there are really no errors, or I'm just not well versed in working with memory.
Here's example
inputs
xUbbemehbT
XYlloworld
should return
Helloworld
I really don't understand why it returns me that, here is code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INT_MSG_LEN 50;
enum {NO_ERROR = 0,
ERROR_INPUT = 100,
ERROR_LEN = 101};
static const char *error_texts[] = { "Error input!",
"Error lenght"};
void shift(char *msgEnc, char *msg, char *msgRes, char *mainMsg, char *alphabet, int offset);
void report_error(int error);
void print_error(int error);
int get_sameletters(char *msg, char *msgRes, int offset);
int get_letter(char letter, char *alphabet);
int compare(char *msgEnc, char *msg, char *msgRes, char *alphabet, int offset);
char *read_Input_Msg(int *msglen);
int main(int argc, char *argv[])
{
int ret = NO_ERROR;
char *msgEnc, *msg, *msgRes, *mainMsg, alphabet[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int msgEncLen, msgLen;
msgEnc = msg = msgRes = mainMsg = NULL;
msgEncLen = msgLen = 0;
msgEnc = read_Input_Msg(&msgEncLen);
if (msgEnc)
msg = read_Input_Msg(&msgLen);
if (msgEnc == NULL || msg == NULL)
ret = ERROR_INPUT;
else if (msgEncLen != msgLen)
ret = ERROR_LEN;
if (ret == NO_ERROR)
shift(msgEnc, msg, msgRes, mainMsg, alphabet, msgEncLen);
else
print_error(ret);
free(msgEnc);
free(msg);
free(msgRes);
free(mainMsg);
return ret;
}
void shift(char *msgEnc, char *msg, char *msgRes, char *mainMsg, char *alphabet, int offset)
{//function for decoding text by a defined offset
int dis;
dis = compare(msgEnc, msg, msgRes, alphabet, offset);
for (int i = 0; i<offset-1; i){
if ((msgEnc[i] >= 'a' && msgEnc[i] <= 'z') || (msgEnc[i] >= 'A' && msgEnc[i] <= 'Z')){
mainMsg[i] = msgEnc[i dis];
break;
}
}
for(int i = 0; i<offset-1; i)
printf("%c", mainMsg[i]);
}
void report_error(int error)
{//prints error
if (error >= ERROR_INPUT && error <= ERROR_LEN)
fprintf(stderr, "%s\n", error_texts[error - ERROR_INPUT]);
}
void print_error(int error)
{//what error it is
switch (error){
case ERROR_INPUT:
report_error(ERROR_INPUT);
break;
case ERROR_LEN:
report_error(ERROR_LEN);
break;
}
}
int get_sameletters(char *msg, char *msgRes, int offset)
{//gets count of sameletters between two strings
int sameLetters = 0;
for (int i = 0; i<offset-1; i){
if (msg[i] == msgRes[i])
sameLetters ;
}
return sameLetters;
}
int get_letter(char letter, char *alphabet)
{
int k;
for (int i=0; alphabet[i]; i){
if (letter == alphabet[i])
k = i;
}
return k;
}
int compare(char *msgEnc, char *msg, char *msgRes, char *alphabet, int offset)
{//calculate a distance between first input string and string what will get after decryption
int distance, max = 0;
for (int i = 0; alphabet[i]; i){
for (int j = 0; msgEnc[j]; j){
if ((msgEnc[i] >= 'a' && msgEnc[i] <= 'z') || (msgEnc[i] >= 'A' && msgEnc[i] <= 'Z'))
msgRes[j] = alphabet[(get_letter(msgEnc[j], alphabet) i) % 52];
}
int sameLetters = get_sameletters(msg, msgRes, offset);
if (sameLetters > max){
max = sameLetters;
distance = i;
}
}
return distance;
}
char *read_Input_Msg(int *msglen)
{//input messages, at the same time counts the length of the entered string
int capacity = INT_MSG_LEN;
char *msg = malloc(capacity);
int c, len = 0;
while ((c = getchar()) != EOF && c != '\n'){
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
free(msg);
msg = NULL;
len = 0;
break;
}
if (len == capacity){
char *tmp = realloc(msg, capacity * 2);
if (tmp == NULL){
free(msg);
msg = NULL;
len = 0;
break;
}
capacity *= 2;
msg = tmp;
}
msg[len ] = c;
}
*msglen = len;
return msg;
}
CodePudding user response:
here is valgrind complaining, I know this is not an answer but you seem to have a problem with your valgrind, maybe this will help
==7662== Invalid write of size 1
==7662== at 0x1096C9: compare (hello.c:110)
==7662== by 0x1093CF: shift (hello.c:55)
==7662== by 0x109338: main (hello.c:41)
==7662== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7662==
==7662==
==7662== Process terminating with default action of signal 11 (SIGSEGV)
==7662== Access not within mapped region at address 0x0
==7662== at 0x1096C9: compare (hello.c:110)
==7662== by 0x1093CF: shift (hello.c:55)
==7662== by 0x109338: main (hello.c:41)
110 is this line
msgRes[j] = alphabet[(get_letter(msgEnc[j], alphabet) i) % 52];
CodePudding user response:
You fail because you call shift with msgres == null
msgEnc = msg = msgRes = mainMsg = NULL; <<<<==========
msgEncLen = msgLen = 0;
msgEnc = read_Input_Msg(&msgEncLen);
if (msgEnc)
msg = read_Input_Msg(&msgLen);
if (msgEnc == NULL || msg == NULL)
ret = ERROR_INPUT;
else if (msgEncLen != msgLen)
ret = ERROR_LEN;
if (ret == NO_ERROR)
shift(msgEnc, msg, msgRes, mainMsg, alphabet, msgEncLen); <<<<======
CodePudding user response:
I changed a one part in main to
int ret = NO_ERROR;
char *msgEnc, *msg, alphabet[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int msgEncLen, msgLen;
msgEnc = msg = NULL;
msgEncLen = msgLen = 0;
msgEnc = read_Input_Msg(&msgEncLen);
if (msgEnc)
msg = read_Input_Msg(&msgLen);
if (msgEnc == NULL || msg == NULL)
ret = ERROR_INPUT;
else if (msgEncLen != msgLen)
ret = ERROR_LEN;
if (ret == NO_ERROR){
char msgRes[msgEncLen], mainMsg[msgEncLen];
shift(msgEnc, msg, msgRes, mainMsg, alphabet, msgEncLen);
}else
print_error(ret);
But still have that error, and I really don't understand what's wrong with 110 line
msgRes[j] = alphabet[(get_letter(msgEnc[j], alphabet) i) % 52];