Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
This problem aims to apply Caesar Cipher. The goal is to encrypt a user defined message. The problem requires us to get the key using the command prompt. After getting the message and the key we must encrypt each character by moving by the key. e.g. if the key is 1 then A - B and b - c and z - a, if the key is 2 then a - c, D - F etc... I have made a very solid program and it seems very correct yet when I use the check50 to check my code it appears so many errors yet the outputs are the same... I just don't get what's wrong with my code..
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
for (int i = 0; argv[1][i] != '\0'; i++)
{
if (isalpha(argv[1][i]))
{
printf("Usage: ./caesar key\n");
return 1;
}
}
int key = atoi(argv[1]);
string ptext;
ptext = get_string("plaintext: ");
printf("ciphertext: ");
int n = strlen(ptext);
for (int i = 0; i <= n; i++)
{
if (isupper(ptext[i]))
{
printf("%c", (((ptext[i] + key) - 65) % 26) + 65);
}
else if (islower(ptext[i]))
{
printf("%c", (((ptext[i] + key) - 97) % 26) + 97);
}
else
{
printf("%c", ptext[i]);
}
}
printf("\n");
return 0;
}
link to check50
https://submit.cs50.io/check50/f7714d6b10c0b2e9fd1c1f01f4209195d8dc5163
You're outputting the null terminator character.
int n = strlen(ptext);
for (int i = 0; i <= n; i++)
You should only loop to i < n.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 months ago.
Improve this question
Sorry, I know this has been asked before but I have read all the answers and nothing works! Please help.
When I check acutal and expected outputs, they match, but in check50 It gives an error message.
Here is the link for check50 results: https://submit.cs50.io/check50/6d939efb8a55e3fadec1c60952311f6198cd0eb0
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
char crypt(int k,char w)
{
if ('a'<= w && w <='z')
{
return (((w-'a')+ k)%26+'a');
}
else if ('A' <= w && w <= 'Z')
{
return (((w -'A') + k) % 26 + 'A');
}
else
{
return (w);
}
}
int main(int argc, string argv[])
{
//input check
if (argc != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
int lngg = strlen(argv[1]);
for (int i = 0; i < lngg; i++)
{
if (isdigit(argv[1][i]) == 0)
{
printf("Usage: ./caesar key\n");
return 1;
}
}
int key = atoi(argv[1])%26;
//input
string plain = get_string("plaintext: ");
//crpypt starts
printf("ciphertext: ");
int lng = strlen(plain)+1;
for (int a = 0; a < lng ;a++)
{
printf("%c", crypt(key, plain[a]));
}
printf("\n");
}
Hi, When I look expected and actual outputs, everything seems perfect but it errors
The problem is that you are also printing the terminating null character to standard output using printf. This character is not printable, so you cannot see it, but check50 does detect it and therefore reports that your program failed.
The loop
for(int a=0; a<lng ;a++)
{
printf("%c",crypt(key,plain[a]));
}
will run for strlen(plain)+1 iterations, because that is the value to which you set the variable lng.
You should instead set the value of lng to strlen(plain), in order to prevent the terminating null character from being printed.
#w is correct.
Also, code can avoid 2 passes down the string and do only 1.
// int lng = strlen(plain)+1;
// for (int a = 0; a < lng ;a++)
for (int a = 0; plain[a] != '\0'; a++)
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{ // see if it is correct input if not then reset and print the right way
if (argc != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
for (int i = 0; i < strlen(argv[1]); i++)
{
if (!isdigit(argv[1]))
{
printf("Usage: ./caesar key\n");
return 1;
}
// cipher the text
int k = atoi(argv[1]);
string plaintext = get_string("Plain text: ");
printf("Cipher text: ");
// printing out the ciphered text
for (int j = 0; j < strlen(plaintext); j++)
if (isupper(plaintext[j]))
{
printf("%c", (plaintext[j] - 65 + k) % 26 + 65);
}
else if (islower(plaintext[j]))
{
printf("%c", (plaintext[j] - 97 + k) % 26 + 97);
}
else
{
printf("%c", plaintext[j]);
}
}
printf("\n");
}
the problem is that when I run it as it should be it only says segmentation fault. I think that the problem is at the top but im not sure
Most of your problem is simply trying to deal with the logic needed to handle that argument Cipher key. Remember, it is an input like any other, so it should be treated first, separately.
Also, avoid aliases for standard objects. It does absolutely nothing to improve readability. (It does the opposite, in fact. Any C programmer will first ask: “what is different about a string and a char *?” And then spend time only to figure out that there isn’t any. So, don’t do that.)
Finally, avoid magic numbers when dealing with character strings. Just use the character literal directly. It makes life so much easier when reading the code.
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char * argv[]) // DON’T use aliases like “string” for “char *”
{
if (argc != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
int k = atoi(argv[1]); // try to turn the argument string into the Caesar offset value
if (k == 0) // fail if non-numeric input (or if input is actually “0”)
{
printf("Invalid key\n");
return 1;
}
const char * plaintext = get_string("Plain text: ");
// Convert the plaintext to the ciphertext
printf("Cipher text: ");
for (int j = 0; j < strlen(plaintext); j++)
{ // <-- don’t forget compound statement braces
if (isupper(plaintext[j]))
{
printf("%c", (plaintext[j] - 'A' + k) % 26 + 'A'); // prefer 'A' instead of 65
}
else if (islower(plaintext[j]))
{
printf("%c", (plaintext[j] - 'a' + k) % 26 + 'a');
}
else
{
printf("%c", plaintext[j]);
}
}
printf("\n");
return 0;
}
Apart from those minor problems, you did a pretty good job! Keep it up!
EDIT
Oh yeah, almost forgot. Did you need to free(plaintext) before main() terminates?
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am currently doing CS - PSET2, and I wrote the code below.
Everything is working, but now that I am re-reading it, I don't understand why.
The doubt is with line 11: if(isdigit(argv [1][i])).
Let's say I write "35", first char is a number, so loop is true and it starts --> I have to write a string (Line 16).
Now program will check the second char, "5", it is a number, true --> I have to write a string again theoretically.
But why not? Why don't I get double results for everything?
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main (int argc , string argv [])
{
if (argc == 2 && isdigit(argv [1]))
{
int n = strlen(argv [1]);
for (int i=0; i<n; i++)
{
if(isdigit(argv [1][i]))
{
string plaintext = get_string("Plaintext: ");
int key = atoi(argv[1]);
int l = strlen(plaintext);
for(int p=0; p <l; p++)
if isupper(plaintext[p])
{
printf("%c", (((plaintext[p] - 'A') + key) % 26) + 'A');
}
else if islower(plaintext[p])
{
printf("%c", (((plaintext[p] - 'a') + key) % 26) + 'a');
}
else
{
printf("%c", plaintext[p]) ;
}
return 0;
}
else
{
printf("Nope\n");
return 1;
}
}
}
else
{
printf("Nope\n");
return 1;
}
}
You have a return 0; statement inside the if that checks for a digit. This will cause it return before it can loop again. Just get rid of that return.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Hey all I have been trying to do the Cs50 course with harvard and am doing the 2nd week Ceasar assignment. For some reason I can't seem to solve this error and I can't seem to locate what the problem is. I've tried changing the bracket style from { to [ and ( but that isn't working and as far as I can tell I've declared everything correctly. It may have something to do with the semi at the end of the int main() but when I remove it I get another error telling me it should be there. The error message is ceasar.c:9:1: error: expected identifier or '(' { referring to the { between the int num = and the k == argv. I've posted the code below. Any help would be appreciated, thanks!!
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(int argc, string argv[]);
int num;
{
k == argv[2];
if(argc != 2)
{
printf("K not included in command");
return 1;
}
string s = get_string("Insert Lowercase Message:");
for (int i = 0, n = strlen(s); i < n; i++)
{
if (s[i] >= 'A' && s[i] <= 'Z')
{
num = s[i] - 'A';
}
else if (s[i] >= 'a' && s[i] <= 'z')
{
num = s[i] - 'a';
}
Output[i] = (num + k)%26;
}
printf("Secret message %s\n", output[i]);
}
The following lines are problematic:
int main(int argc, string argv[]);
int num;
{
k == argv[2];
if(argc != 2)
You need to remove the semicolon after main;
You need to mov int num to after the opening {;
You need a declaration for k;
You need to check the number of arguments before attempting to assign argv[2] to k;
If you are expecting 2 arguments (argc == 2), then the second argument is at argv[1], not argv[2];
You need to use = for assignment, not ==;
k is an int, whereas argv[1] points to a string representation of an integer value; you will need to use atoi or strtol to convert the contents of argv[1] to the equivalent integer value;
Putting that all together:
#include <stdlib.h> // for atoi
...
int main( int argc, char **argv )
{
int num;
int k;
if ( argc != 2 )
// error
k = atoi( argv[1] );
and proceed from there.
Some words of warning - the CS50 library grossly misrepresents how strings and string processing work in C. Do not expect anything you learn in this course with respect to strings to carry forward in other environments.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am trying to implement the Caesar cipher but I'm not getting the expected output. What's wrong with the code?
Key: 3
Input: Hello
Output I'm getting: KNUUX
Expected Output: KHOOR
Code:
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
if(argc!=2)
{
return 1;
}
int k, i;
k = atoi(argv[1]);
printf("Enter the String to Encrypt: ");
string s=GetString();
for(i=0; i<strlen(s); i++)
{
if('A'>=s[i]<='Z')
{
s[i]=((s[i] - 'A' + k)%26) +'A';
}
else if('a'>=s[i]<='z')
{
s[i]=((s[i] - 'a' + k)%26) +'a';
}
}
printf("The Encrypted Text is %s\n",s);
}
if('A'>=s[i]<='Z')
Is certainly not doing what you seem to be expecting.
You probably want:
if ( (s[i] >= 'A') && (s[i] <= 'Z') )
for(i=0; s[i]; ++i)
if(isalpha(s[i]))
s[i]=(toupper(s[i]) - 'A' + k)%26 +'A';