Segmentation fault clang - c

what I try to do
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[]) {
for (int i = 0; i < strlen(argv[1]); i++) {
if (isalpha(atoi(argv[i]))) {
printf("Usage: ./caesar key\n");
return 1;
}
}
int k = atoi(argv[1]);
if (argc == 2) {
string pt = get_string("plaintext: ");
printf("ciphertext: ");
char ct[strlen(pt)];
for (int i = 0; i < (strlen(pt)); i++) {
if (isalpha(pt[i]) && isupper(pt[i])) {
ct[i] = ((pt[i] - 65) + k) % 26;
printf("%c", ct[i] + 65);
} else if (isalpha(pt[i]) && islower(pt[i])) {
ct[i] = ((pt[i] - 97) + k) % 26;
printf("%c", ct[i] + 97);
}
}
printf("\n");
}
else if (argc != 2) {
printf("Usage: ./caesar keyn\n");
return 1;
}
}
if I pass 20x it must show me (Usage: ./caesar)
instead of that I get Segmentation fault why!!
can anyone help me and I will be thanx

Your first loop iterates through the number of characters in the first command argument, and tries to access the command argument of that index. So if you have only one command argument, but that argument has more than 2 characters then you will be trying to access an element in argv beyond the end of the array.

Related

How to handle handles lack of argv[1] and handles too many arguments in caesar?

I finished Caesar pset2 for CS50, but when I run it for a check-up, I get 2 errors. One for how handles lack of argv[1] and the other being too many arguments. I've been stuck on this for several hours and haven't made any progress. Any tips on how to move forward?
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
int strtoint;
int onlydigits = 0;
if (argc == 2) //Checks the program with one command-line argument
{
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if (isdigit(argv[1][i]))
{
onlydigits += 1;
}
}
if (onlydigits == strlen(argv[1])) //Checks if characters are digits
{
strtoint = atoi(argv[1]); //Converts string to int
string plain = get_string("plaintext: "); //Prompt user for input
printf("ciphertext: ");
for (int j = 0, m = strlen(plain); j < m; j++) //Iterate over each character for plaintext
{
if (isalpha(plain[j]) && isupper(plain[j])) //Checks if characters are uppercase
{
printf("%c", (((plain[j] - 65) + strtoint) % 26) + 65);
}
else if (isalpha(plain[j]) && islower(plain[j])) //Checks if characters are lowercase
{
printf("%c", (((plain[j] - 97) + strtoint) % 26) + 97);
}
else
{
printf("%c", plain[j]); //Prints as is if neither of the above
}
}
printf("\n"); //Prints a new line
return 0;
}
else
{
printf("Usage: ./caesar key\n");
return 1;
}
}
}
output for code

CS50 Caesar - Check50 won't validate my code

I know that this question have been asked before, but I still can't find the clue to the problem in my code.
My program works apparently fine, but I'm not able to pass the check50 test. From what I understand, the issue may be related to the fact that the null \0 is printed. But I don't know how to modify that. Could you please help me?
This is my code:
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
bool only_digits(string s);
char rotate(char c, int n);
int main(int argc, string argv[])
{
string h = argv[1];
if (argc != 2 || !only_digits(h) || h <= 0)
{printf("Usage: ./caesar key\n");
return 1;
}
else
{
int key = atoi(argv[1]);
string plaintext = get_string("plaintext: ");
int f = strlen(plaintext);
printf("ciphertext: ");
for(int q = 0; q < f; q++)
{
printf("%c", rotate(plaintext[q], key));
}
printf("\n");
}
return 0;
}
bool only_digits(string s )
{
for (int i = 0, n = strlen(s); i < n; i++)
{
char digit = s[i];
if (!isdigit(digit))
return false;
}
return true;
}
char rotate(char c, int n)
{
if(isupper(c) && (c != '\0'))
{
printf("%c", (((c - 65) + n) % 26) + 65);
}
else
if(islower(c) && (c != '\0'))
{
printf("%c", (((c - 97) + n) % 26) + 97);
}
else
printf("%c", c);
return 0;
}
This is a caption of check50's check:
check50
rotate always returns 0, so printf("%c", rotate(plaintext[q], key)); is causing the letters you output to be interspaced with NUL characters.
I would keep that printf, but change rotate to return the character instead of printing it.

CS50 Caesar segmentation fault

I am new here and working on the second homework Caesar of cs50, it seems most of my review is correct except the last one -- I cannot handle the situation of lacking argv[1], which means if I only type ./caesar, it will return segmentation fault. I am wondering why this code if (argc != 2) cannot return 0 when argc == 1, however it works when argc > 1, I find that is weird. Can anyone help me?? Thanks in advance!
# include <stdio.h>
# include <cs50.h>
# include <string.h>
# include <ctype.h>
# include <math.h>
# include <stdlib.h>
int check_the_key(int argc, string y);
int main(int argc, string argv[])
{
string x = argv[1];
int y = argc;
int k = check_the_key(y, x);
if (k == 0)
{
printf("ERROR!!!!!\n");
return 1;
}
else
{
// printf("The key is %i\n", k);
string text = get_string("Input your text:");
int i;
int n;
printf("ciphertext: ");
for (i = 0, n = strlen(text); i < n; i++)
{
if (islower(text[i]))
{
printf("%c", (text[i] - 97 + k) % 26 + 97 );
}
else if (isupper(text[i]))
{
printf("%c", (text[i] - 65 + k) % 26 + 65);
}
else
{
printf("%c", text[i]);
}
}
printf("\n");
return 0;
}
}
int check_the_key(int argc, string y)
{
int number = argc;
string key = y;
int numberkey = atoi(key);
if (argc != 2)
{
return 0;
}
else
{
if (numberkey > 0)
{
return numberkey;
}
else
{
return 0;
}
}
}
I know what is going on! Because I need to pass some value into atoi(), if I only call ./caesar, there is no value I can pass into atoi(), so it causes segmentation fault. Which means I need to change code order slightly, put int numberkey = atoi(key); inside the else loop. So the code will run if (argc != 2) first, if no, then go to the next step! Here is the code after change.
int check_the_key(int argc, string y)
{
int number = argc;
string key = y;
if (argc != 2)
{
return 0;
}
else
{
int numberkey = atoi(key);
if (numberkey > 0)
{
return numberkey;
}
else
{
return 0;
}
}
}

How to Preserve Case of Inputted Chars in C?

The user inputs chars that can be uppercase or lowercase. I need to spit an answer back that preserves the case of the inputted char after that char is processed by my code. How do I preserve case when the char was converted to its ASCII value and then to its alphabetical index equivalent.
Here is my code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
int counter = 0;
if (argc == 2) {
for (int k = 0; k < strlen(argv[1]); k++) {
if (isdigit(argv[1][k])) {
counter++;
}
}
if (strlen(argv[1]) == counter)
{
string s = get_string("plaintext: ");
printf("ciphertext: ");
for (int i = 0; i < strlen(s); i++) {
int c = (int) s[i];
if (c >= 97 && c <= 122)
{
printf("%i\n", (((c % 32) - 1 + atoi(argv[1]))) % 26);
}
printf("\n");
if (c >= 65 && c <= 90)
{
printf("%i", (((c % 32)) - 1 + atoi(argv[1])) % 26);
}
printf("\n");
}
} else {
printf("Usage: ./caesar key\n");
}
}
}
Expected behavior would print Zoo as "App" if Key entered in command line were 1.

Wrapping Text Using Modulo

I am trying to cipher some plain text using a string key. Anyway if the plain text is greater than the key the key is suppose to continue using the key..I have used modulo to make the key start over again but for some reason it is not working...what is wrong with the code? By the way the key status upper or lower status is not a factor so this is why I change it to lower. Any help rendered would be appreciated. //Code cleaned up as suggested.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include<stdlib.h>
#include<ctype.h>
int main (int argc, string argv[])
{
if (argc != 2)
{
printf("Ouch missing key\n");
return 1;
}
//get encryption keyword from argv array
string k= (argv[1]);
//test for non aplha character in plain text message
int x;
for (x = 0; x <strlen(argv[1]); x++)
{
if(isalpha(k[x]) == false)
{
printf("Ouch ensure value is alphabetical only\n");
return 1;
}
}
string m;
m = GetString(); //get plain text from prompt
for (int i= 0, j = 0; i< strlen(m) && j<= strlen(k); i++, j++)
{
if (
isalpha(m[i]) && isupper(m[i]))
{
m[i]= (m[i]-'a' + (tolower(k[j % strlen(k)])-'a')) % 26 + 'A';
}
else if (
isalpha(m[i]) && islower(m[i])
)
{
m[i] = (m[i] - 'a' + (tolower(k[j %strlen(k)])- 'a')) % 26 + 'a';
}
else
m[i] = m[i];
}
printf("%s\n", m);
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <cs50.h>
int main (int argc, string argv[]){
if (argc != 2){
printf("Ouch missing key\n");
return 1;
}
string k = argv[1];
int len_k = strlen(k);
for (int i = 0; i < len_k; ++i){
if(isalpha(k[i]))
k[i] = tolower(k[i]);
else {
printf("Ouch ensure value is alphabetical only\n");
return 1;
}
}
string m;
m = GetString();
for (int i= 0; i< m[i] ; ++i){
if(isupper(m[i]))
m[i]= (m[i]-'A' + k[i % len_k] - 'a') % 26 + 'A';
else if(islower(m[i]))
m[i]= (m[i]-'a' + k[i % len_k] - 'a') % 26 + 'a';
else
m[i] = m[i];//no effect, no need
}
printf("%s\n", m);
free(m);
return 0;
}
If your coding language is C fix main() by,
int main (int argc, string argv[])
to
int main (int argc, char * argv[])

Resources