-3

I've been trying to fix this source code for a long time but the compiler still shows error.

#include<cs50.h>    
#include<stdio.h>   
#include<string.h>
#include<stdlib.h>
#include<ctype.h>

int main(int argc, char* argv[])
{
    char ptext[40];
    int i=0;
    if(argc!=2)
    {
        printf("invalid key");
        return 1;
    }
    else
        printf("enter plain text\n");
    ptext= GetString();
    int key= atoi(argv[1]);
    int n=strlen(ptext);
    while( ptext[i]!= '\0')
    {
        if( ptext[i]>65 && ptext[i]<90)
        {
            int c= (ptext+key)%26;
            int d= c+26;
            printf("%c", d);
        }
        else if( ptext[i]>97 && ptext[i]<122)
        {
            int c= (ptext+key)%26;
            int d= c+26;
            printf("%c", d);
        }
        else
        {
            printf("%c",ptext[i]);
        }
        i++;
    }
}

The errors it shows while compiling are array type 'char [40]' is not assignable (which does nothing even when a number smaller than 40 is entered or the brackets are left empty), and invalid operands to binary operation int c = (ptext+key)%26.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
jigl
  • 1

2 Answers2

1

Couple of things:

What you really need ptext to be is a char*, not an array. I'm guessing GetString() will return a string, or a char[]/char* what have you. Depending on how GetString() works, you might need to test for a NULL return.

At the line int c= (ptext+key)%26; it appears you're trying to process ptext[i]. Perhaps you forgot to include the indexer?

And just a suggestion, if using ASCII, at lines like if( ptext[i]>65 && ptext[i]<90) you can use the char values themselves instead of numbers so you don't have to pore over the ASCII tables. You can do it like so: if(ptext[i] >= 'A' && ptext[i] <= 'Z').

Notice above, also, I changed the comparators > and < to >= and <=. Are not 'A' and 'Z' valid characters?

When using the modulo as you are, for a Caesar Cipher, you want the index of the character in the alphabet. So in the case it's a capital letter, you want to subtract 'A' (or as you so aptly know, 65 in ASCII) like so : `int c= (ptext[i] - 'A' + key) % 26;'.

Gutblender
  • 1,340
  • 1
  • 12
  • 25
  • 1
    Certainly you mean to add `'A'` back with `int c = (ptext[i] - 'A' + key) % 26 + 'A'; printf("%c", c);` – chux - Reinstate Monica Aug 21 '14 at 20:01
  • Yes, thank you, or in the next line with `int d = c + 'A';`. Indeed that's another fix that needs to happen. Indeed I say remove the declaration of `d` entirely as it's useless. – Gutblender Aug 21 '14 at 20:08
  • 3
    You can use `'A'` whether or not you are using ASCII , and it makes the code easier to read in both cases. (However `'A'` to `'Z'` are not consecutive in some other character sets!) – M.M Aug 21 '14 at 20:18
  • Veering OT, but still: for a nonconsecutive encoding - not only useful for weird encodings such as [EBCDIC](http://en.m.wikipedia.org/wiki/EBCDIC) where `A..Z` is not, but also for alphabets which are carelessly stored out-of-order in codepages (or, indeed, in Unicode itself) -, you could create a static string containing all characters in the proper order. – Jongware Aug 21 '14 at 22:02
1

Change char ptext[40]; to char *ptext;

The GetString() function from cs50.h dynamically allocates some memory and returns a pointer to it. In C it is not possible to assign to an array, nor to return an array.

When you have finished accessing the string's contents, do free(ptext); to release the memory used.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • I made the suggested changes..and it does not show any error while compiling now but shows question marks in place of every ciphered text in result alongwith segmentation fault (core dumped). what does that mean? – jigl Aug 24 '14 at 17:48
  • First of all learn how to debug. You should be able to find out on your own which line had the segfault and what the variables were – M.M Aug 24 '14 at 19:36