This segment of code is meant to check if a user has entered only one numeric command-line argument, and return an error code of "1" if this is not the case. I have the code set up so that it first checks if argc is anything other than 2. Unfortunately, I am still receiving Segmentation Faults if no command line argument is entered, and I'm not sure why this code doesn't catch a null amount of command line arguments.
I tried moving the "if (argc !=2)" formula above the entire "for" statement to try and catch the command line argument issue right from the beginning, but I received the same result.
My question is, why am I receiving a Segmentation Fault when no command line argument is provided, and what am I missing to ensure the program doesn't Seg Fault with no command line argument?
Due to course policy, I will only be providing the segment of code in question.
#include <unistd.h>
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
// add'l variables //
int k = atoi(argv[1]);
for (int i = 0; i < strlen(argv[1]); i++)
{
if (argc != 2)
{
printf("Please enter only 1 command-line argument.\n");
return 1;
}
else if (!isdigit(argv[1][i]))
{
printf("Usage: ./caesar key\n");
return 1;
}
}
// add'l code //
Error as shown in Terminal
You must first check the argc before using the argv[1], because argv[1] may not have a valid pointer if argc < 2. A corrected version of your code could be like that:
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
int i = 0;
if (argc != 2) {
printf("Please enter only 1 command-line argument.\n");
return 1;
}
while (isdigit(argv[1][i]))
++i;
if (argv[1][i] != '\0') {
printf("Usage: ./caesar key\n");
return 1;
}
return 0;
}
Related
when I input debug50 Caeser 1024 into my code space argc shows as 2 which is correct but argv shows as 0x7ffd87a68798
as shown here and idk why it doesn't show as 1024?
this is the first time I've used command line arguments so would appreciate any help, please.
This is my code so far also would appreciate any checks on my function I think that's wrong as well :/
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
bool only_digit(string argv[1]);
int main(int argc, string argv[])
{
//Make sure program was run with command line argument (argc)
if (argc == 2){
return 0;
}
else{
printf("Usage: ./caesar key\n");
return 1;
}
}
//Make sure every character in argv[1] is a number
bool only_digit(string argv[1]){
if (isdigit((*argv[1]))){
return true;
}
else{
return false;
}
}
You should check if no. of arguments doesn't match what you expect first and return if it doesn't.
Also, you should learn how to declare/define functions properly with arguments. argv[1] means you are expecting an array of strings of size 1.
Also, your function can be a single return statement.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
bool only_digit(string s);
int main(int argc, string argv[]) {
// Make sure program was run with command line argument (argc)
if (argc != 2) {
printf("Usage: ./caesar key\n");
return 1;
}
printf("%d\n", only_digit(argv[1]));
}
// Make sure every character in argv[1] is a number
bool only_digit(string s) {
return isdigit(*s);
}
I'm on the stage where we need to correctly setup the command line argument to take only digits and to break out of the code if the user types anything else other than a digit. (leaving it empty, inputting two digits, inputting text, inputting two pieces of text etc.)
So I made the program work correctly if the user types more than one command line argument or one command line argument which isn't a digit. My problem is that if I leave the command line argument blank the program gives me a segmentation fault and it doesn't work as intended if I type a single command line like "1d". Can anyone tell me where I went wrong? I'm stuck. Here's the code:
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
bool only_digits(string argv[]);
int main(int argc, string argv[])
{
bool digits = only_digits(argv);
if(argc != 2 || digits == false)
{
printf("Usage: ./caesar key\n");
return 1;
}
else
{
return 0;
}
}
bool only_digits(string argv[])
{
bool digit = false;
for(int i = 0; i < strlen(argv[1]); i++)
{
if(isdigit(argv[1][i]))
{
digit = true;
}
}
return digit;
}
You have two problems:
You're calling only_digits() before checking whether argv[1] exists. So you get a segfault if there are no command-line arguments. Fix this by calling only_digits() after the argc check.
The condition in only_digits() is backwards. It returns true if any character is a digit, but it's supposed to return true only if all the characters are digits.
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
bool only_digits(string argv[]);
int main(int argc, string argv[])
{
if(!(argc == 2 && only_digits(argv)))
{
printf("Usage: ./caesar key\n");
return 1;
}
return 0;
}
bool only_digits(string argv[])
{
for(int i = 0; i < strlen(argv[1]); i++)
{
if(!isdigit(argv[1][i]))
{
return false;
}
}
return true;
}
I try to get the user to type a specific command line to execute my program, but ./caesar leads to segmentation fault, while no return statement is included. With return statement, everything works perfectly.
Can someone explain to me why that's the case and if there is another solution to fix this?
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
int main(int argc, string argv[])
{
if(argc != 2)
{
printf("Usage: ./caesar key\n");
//return 1;
}
for(int i = 0, p = strlen(argv[1]); i < p; i++)
{
if(isalpha(argv[1][i]))
{
printf("Usage: ./caesar key\n");
}
}
}
return exits your function early, so the code afterwards doesn't get run. If you don't provide an argument, argc won't be 2, and argv[1] wouldn't be a valid string. With a return, then usage message prints and then the return stops execution there, so you don't try to call strlen(argv[1]), which will segfault.
Without the return, you print the usage message, but the code keeps running, and you call strlen(argv[1]), which will cause a segfault.
I am currently doing cs50 course, I am doing the caesar cipher problem and have come across a problem.
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
// argument count, array of strings
int main (int argc, string argv[])
{
//checking there is only one command line argument, checking if digit
if (argc == 2 && isdigit(*argv[1]))
{ //atoi converts string to int
int k = atoi(argv[1]);
//get plaintext
string s = get_string ("Plain text: ");
printf("ciphertext: \n");
if (argc !=2)
printf("Usage: ./ceasar\n");
}
}
I cannot get my program to print "Usage: ./caesar"
If I enter ./cipher 2 it returns
Plaintext:
but if I enter say ./caesar g it returns to a blank line in terminal.
Any help would be appreciated.
You miss an else branch:
if (argc == 2 && isdigit(*argv[1]))
{ //atoi converts string to int
int k = atoi(argv[1]);
//get plaintext
string s = get_string ("Plain text: ");
printf("ciphertext: \n");
... // the rest of your code
}
else
{
printf("Usage: ./ceasar\n"); // You mean Usage: ./ceasar param
}
It's a better practice to check arguments first and exit earlier. Here is a link to run the code. You might need it later when you encounter segfaults.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// argument count, array of strings
int main(int argc, string argv[]) {
if (argc != 2) {
printf("Usage: ./ceasar\n");
exit (1);
}
// checking there is only one command line argument, checking if digit
if (argc == 2 && isdigit(*argv[1])) { // atoi converts string to int
int k = atoi(argv[1]);
// get plaintext
string s = get_string("Plain text: ");
printf("ciphertext: \n");
}
return 0;
}
Your if condition has no else branch,
if (argc == 2 && isdigit(*argv[1]))
checks if the input is a digit, if g is entered, the condition fails and the code in the if block is not executed, and the program exits with exit code 0. Use:
if (argc == 2 && isdigit(*argv[1]))
{
//Your code
}
else
{
//Else code if your condition fails
}
I am stuck trying to iterate over each character to detect whether or not it is a digit, while only printing the answer once. The problem I'm having is I can get it to detect whether a character is a digit or not, but it prints out an answer for each number I put in until it reaches a letter. I'm looking how to get it to detect whether or not the input is a number or letter, and then make a decision on what to print out instead of printing success every time it detects a number. Feel like its something with my for loop but cant quite figure it out. Thanks.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
string n = argv[1];
if (argc != 2)
{
printf("usage: ./caesar key\n");
return 1;
}
else
{
for(int i = 0, length = strlen(n); i < length; i++)
if(!isdigit(n[i]))
{
printf("usage: ./caesar key\n");
return 1;
}
else
{
int convert = atoi(n);
printf("Success\n");
printf("%i\n", convert);
}
}
}
The problem is that inside the for you have an if-else statement... that means that one of both will always execute for every iterarion.
For printing success just once, you should erase the else keyword (and for clarity the brackets) but keeping the else code.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
string n = argv[1];
if (argc != 2)
{
printf("usage: ./caesar key\n");
return 1;
}
else
{
for(int i = 0, length = strlen(n); i < length; i++)
{
if(!isdigit(n[i]))
{
printf("usage: ./caesar key\n");
return 1;
}
}
int convert = atoi(n);
printf("Success\n");
printf("%i\n", convert);
}
}
What do I need to change so cs50 Caesar only prints the correct message after i iterate over each character?
It seems you aren't aware that you don't have to do that. The Caesar Specification says:
You can assume that, if a user does provide a command-line argument, it will be a non-negative integer (e.g., 1). No need to check that it’s indeed numeric.