1

I made myself vigenere cypher console program in c. My code have many parts which I do understand, but the output is wrong and don't know how to fix it. My goal is to be able to encipher full paragraph.

Lines 5-36 -> the table. Lines 37-51 -> declarations, inputs, notes. Lines 52-52 -> setting up j for longer input. 59-74 -> comparison inputs with alphabet. 77-81 -> printing out inputs. 82-84 -> length of inputs. 85-892 -> positions in alphabet. 94-121 -> array of array. 122 -> declarations of numbers.. 132-129 -> printing array of array. 130-150 -> my poor encryption.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
    printf("   |\n");
    printf("   |  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  \n");
    printf("---+------------------------------------------------------------------------------  \n");
    printf(" A |  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  \n");
    printf(" B |  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  \n");
    printf(" C |  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  \n");
    printf(" D |  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  \n");
    printf(" E |  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  \n");
    printf(" F |  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  \n");
    printf(" G |  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  \n");
    printf(" H |  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  \n");
    printf(" I |  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  \n");
    printf(" J |  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  \n");
    printf(" K |  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  \n");
    printf(" L |  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  \n");
    printf(" M |  m  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  \n");
    printf(" N |  n  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  \n");
    printf(" O |  o  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  \n");
    printf(" P |  p  q  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  \n");
    printf(" R |  r  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  \n");
    printf(" S |  s  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  \n");
    printf(" T |  t  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  \n");
    printf(" U |  u  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  \n");
    printf(" V |  v  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  \n");
    printf(" W |  w  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  \n");
    printf(" X |  x  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  \n");
    printf(" Y |  y  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  \n");
    printf(" Z |  z  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  \n");
    printf("==================================================================================  \n");
    printf("USE ONLY THIS : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
    printf(" CHARRACTERS  : abcdefghijklmnopqrstuvwxyz\n");
    printf("==================================================================================  \n");
    char s1[20],s2[20];
    char abeceda[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    printf("First input:   ");
    scanf("%s",&s1);
    printf("Secound input: ");
    scanf("%s",&s2);
    int i=0,k=0,j=0,l=0,m=0,y=0,x=0;
    j=strlen(s1),l=strlen(abeceda),m=strlen(s2);
    int r=10;
    int array[50],array0[50];
    printf("\n");
    printf("1-means code found agreement with first input.\n");
    printf("2-means code found agreement with secound input.\n");
    printf("\n");
    printf("number of matches:\n");
    if(strlen(s1)<=strlen(s2))
    {
        j=strlen(s2);
    }
    else{
        j=(strlen(s1));
    }
    for(i=0;i<j;i++){
        for(k=0;k<l;k++){
        //first input
        if(s1[i]==abeceda[k]){
            printf("1");
            //printf("%c ",s1[i]);//printf("%i",k);
            array[y]=k;
            y++;
        }
        //druhe slovo
        if(s2[i]==abeceda[k]){
            printf("2");
            //printf("  |  ");//printf("%c\n",s2[i]);    //printf("%i",k);
            array0[x]=k;
            x++;
        }}}
    printf("\n");
    printf("\n");
        printf("-1-|-2-\n");
    for(i=0;i<j;i++){
        /*for(k=0;k<l;k++){if(s1[i]!=abeceda[k]){ s1[i]=" ";}if(s2[i]!=abeceda[k]){ s2[i]=" ";printf("1");}     printf("\n");   }*/
        printf(" %c | %c\n",s1[i],s2[i]);
        }
    printf("\nlen of s1: %i",y);
    printf("\nlen of s2: %i\n",x);
printf("\n");
    for(k=0;k<j;k++){
    printf("%i,",array[k]);
}
printf("\n");
    for(k=0;k<m;k++){
        printf("%i,",array0[k]);
        }
        printf("\n\n");
        printf("comparing table:\n");
    char Row_Of_Row[26][26]={
    {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'},
    {'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a'},
    {'c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b'},
    {'d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c'},
    {'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','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','a','b','c','d','e'},
    {'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f'},
    {'h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g'},
    {'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h'},
    {'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i'},
    {'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j'},
    {'l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k'},
    {'m','n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l'},
    {'n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m'},
    {'o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n'},
    {'p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'},
    {'q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'},
    {'r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q'},
    {'s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r'},
    {'t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s'},
    {'u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t'},
    {'v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u'},
    {'w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v'},
    {'x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w'},
    {'y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'},
    {'z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y'},
};
    int a=0,b=25,c=0,d=0,e=0;
    for(a=0;a<=b;a++){
    for(c=0;c<=b;c++){
    printf("%c",Row_Of_Row[c][a]);
    }
    printf("\n");
    }
    printf("\n");
char NewRoad[j];
printf("Length of output word is: %i",j);
printf("\n");

printf("encryption: ");
for(a=0;a<j;a++){
    d=array[a];
    e=array0[a];
    printf("%i,%i\n",d,e);
    printf("%c",Row_Of_Row[d][e]);
    //NewRoad[a]=Row_Of_Row[d][e];
    //printf("%c",NewRoad[a]);
    NewRoad[a]=Row_Of_Row[d][e];
    printf("\n");
}
printf("Output is: ");
for(a=0;a<j;a++){
printf("%c",NewRoad[a]);
}
printf("\n%s",NewRoad);
}

Know its ugly but I'm stuck for days. My code has different output depending on size of inputs. I think that is because of compiler but not sure. When I try Visual Studio Code output was also different.

Dev c++ Windows 7:

  1. input: wwww
  2. input: xxxx
    output: "tyza"

Dev c++ Windows 10:

  1. input: wwww
  2. input: xxxx
    output: "tttt"

This is okay but when I tried longer inputs this happened.

  1. input: 35*"w"
  2. input: 35*"x"
    output: "uuutttttttttttttttttttttttttttttttz"

Another issue is:

  1. input: w
  2. input: b
    output: "xřb"

Any ideas why this is happening and how do I fix it? Sorry for mistakes, I'm a beginner.

John Conde
  • 217,595
  • 99
  • 455
  • 496
Justin
  • 41
  • 6
  • 1
    In your post you say that when you enter `35*"w"`, you don't get what you expect. Do you mean you enter 35 `w` characters? If so, you're greatly overrunning your 20 character input buffers. BTW, your compiler should be giving you warnings regarding your `scanf` calls. – Jeff Holt Aug 25 '21 at 15:12
  • Yes, I meant entering 35 w characters. 1.) Compiler didn't give me any warnings but If yes lot of would be explained. 2.) I set maximum size s1,s2 on 120 and enter 35 w, 35 b. When 64 bit compiler is choosen output is: 35 x. Anyway with 32 bit compiler output was: bikmpkacgikacgikdfilnmpfilnqhjmpfil + there was sound of Windows error. Why ? 3.) Why program doesn't work with longer inputs sized on 100 characters when maximum size s1,s2 is set for 350? The program does not even print output, it ends with numbers and then program ends. Why ? What should I do to get rid of these problems ? – Justin Aug 25 '21 at 17:19
  • First thing you should do is edit your post, adding that comment's information, properly formatted. It's a whole lot easier for folks to see everything in context in the post rather than reading a comment conversation. – Jeff Holt Aug 25 '21 at 18:30
  • "sound of windows error" If you mean the IDE is emitting a sound as if there is an error, it might be that the IDE is detecting that the program's exit value was something other than zero. `main` returns an `int`, eventually, to the caller and the caller (probably the IDE) is deciding to emit a sound if the return value is not zero. Each compiler can have different behavior if your `int` function doesn't explicitly return an `int`. I see no `return` statement in your `main` nor do I see a call to `exit`. – Jeff Holt Aug 25 '21 at 18:33
  • Another thing you should do is use your IDE's "format my code so I can read it" button. Then you can copy it to your post. After you copy it to your post, select all that text and press this site's `{}` editor's "format my code verbatim" button. – Jeff Holt Aug 25 '21 at 18:36
  • I just found out that the variable in which the length of the alphabet is stored increases by the size of the second input. The problem arises on line 60. Originally it is `for (k = 0; k – Justin Aug 27 '21 at 18:53

1 Answers1

1

Other than your code not returning an exit value to its caller, you have a memory management problem.

If some code is not properly managing memory, you can often find out where simply by using valgrind. Here's what it says about your code after changing the size of your input arrays from 20 to 100:

$ cat x
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ gcc -g t.c # more recent versions complain about the `scanf` parameters
$ valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ./a.out <x

==20737== Memcheck, a memory error detector
... lots of lines elided
number of matches:
1212121212121212121212121212121212121212121212121212121212121212121212
... lots of lines elided
len of s1: 35
len of s2: 35
... lots of lines elided
22,23
t
22,23
t
22,23
t
==20737== Conditional jump or move depends on uninitialised value(s)
==20737==    at 0x4E79C7B: vfprintf (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4E82AE8: printf (in /usr/lib64/libc-2.18.so)
==20737==    by 0x400E0A: main (t.c:149)
==20737==  Uninitialised value was created by a stack allocation
==20737==    at 0x400C5F: main (t.c:130)
==20737==
==20737== Syscall param write(buf) points to uninitialised byte(s)
==20737==    at 0x4F176B0: __write_nocancel (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4EA79E2: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4EA8E4B: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4EAA9CD: _IO_flush_all_lockp (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4EAAB29: _IO_cleanup (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4E6A09A: __run_exit_handlers (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4E6A134: exit (in /usr/lib64/libc-2.18.so)
==20737==    by 0x4E52D6B: (below main) (in /usr/lib64/libc-2.18.so)
==20737==  Address 0x402112a is not stack'd, malloc'd or (recently) free'd
==20737==  Uninitialised value was created by a stack allocation
==20737==    at 0x400C5F: main (t.c:130)
==20737==
22,23
t
22,23
... lots of lines elided
==20737== ERROR SUMMARY: 5 errors from 3 contexts (suppressed: 2 from 2)

The warning about a problem with a conditional jump in vfprintf, which is caused by a call from printf, which is on line 149 of your file, is partially caused by the way you are allocating memory for NewRoad. Your code is allocating j bytes to it but later on, after printing j characters of NewRoad, your code is printing NewRoad as if it is a null-terminated string. But it's not a null-terminated string.

The rest of the problem is that nowhere are you storing 0 at NewRoad[j]. When printf tries to print NewRoad as a null-terminated string(%s), it goes beyond the memory allocated to it, which results in behavior that is not defined by the C language. That is what is termed "undefined behavior (UB)", which is an incessant C language topic at this site.

The fact that two compilers result in different behavior is exactly why UB is insidious. After all, those two compilers are two implementations of a language and so they can get away with behaving differently because they don't have to behave the same way for an undefined use case.

One thing you can do is allocate j+1 bytes to NewRoad instead of only j bytes. Then, sometime after your last NewRoad modification and before you print NewRoad as a null-terminated string, you can assign 0 to NewRoad[j].

Alternatively, you can make a simpler change without having to modify the amount of memory you allocate to NewRoad or having to store the null-terminator in the character array. This

printf("\n%s",NewRoad);

becomes

printf("\n%.*s", j, NewRoad);

Which "says" print no more than the first j characters of NewRoad.

Jeff Holt
  • 2,940
  • 3
  • 22
  • 29