How to fix Segmentation fault in a command line argument - c

I am trying to create a cipher coder in C, so far I have the following code. The if statement doesn't work properly and pops up segmentation fault whenever something is inputted whether it be a digit or just a letter. The else statement which is supposed to print out how to use the cipher text only prints it out when there is a space.
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main(int argc, string argv[]) //im certain the problem is on this line but I dont know where exactly nor do I know how to fix it
{
if (isdigit(argv[1]))
{
string s = get_string("Cipher Text: ");
}
else
{
printf("Usage: ./caesar key\n");
}
}
I'm certain the error has to deal with the string in the command line argument but I'm not to sure on what steps to take to fix it.

This is a very small program to show how you can access arguments of a C program.
It only uses standard C features (not CS50 or special string type).
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
printf("argc=%d\n", argc);
for (i=0; i < argc; i++)
printf("argv[%d]=%s\n", i, argv[i]);
return 0;
}

Related

Command line argv not showing up during debugging (using github codespace)

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);
}

Segmentation Fault Due to Lack of Command Line Argument (argv[1])

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;
}

How does one correctly format command line arguments?

I am trying to construct a simple programme to acquaint myself with command line functionality, I seem to have formatted something incorrectly, but I find it very difficult to understand precisely what the resulting error message means. My intenion is to create a programme which checks that all the characters in the command line are digits. Here is my code:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
for (int i = 0; i < strlen(argv); i++)
{
if (!isalnum(argv[i]))
{
printf("Please provide letters or numbers only");
}
else
{
printf("Success!");
}
}
}
The error message I receive when I attempt to compile is: c:9:32: error: incompatible pointer types passing 'char **' to parameter of type 'const char *'; dereference with * [-Werror,-Wincompatible-pointer-types].
argv is an array (pointer) of pointers to strings.
isalnum is checking a character, not a whole string, so you will need two loops: to check each strings and to check each characters in the strings.
This code won't get the warning:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
for (int c = 1; c < argc; c++) // loop for checking each strings
{
for (int i = 0; i < strlen(argv[c]); i++) // loop for checking each characters in the strings
{
if (!isalnum(argv[c][i]))
{
printf("Please provide letters or numbers only");
}
else
{
printf("Success!");
}
}
}
}
But you may want this code with implovements:
Print the message only once instead of for each characters.
Use size_t for looping until the length of the string.
Call strlen() once before the loop instead of calling in each iteration.
Use puts instead of printf to print newline character at the end of output.
Add return 0; to clarify that the code returns 0.
Remove unnecessary #includes, including non-standard one.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
int all_ok = 1;
for (int c = 1; c < argc; c++)
{
size_t len = strlen(argv[c]);
for (size_t i = 0; i < len; i++)
{
all_ok = all_ok && isalnum(argv[c][i]);
}
}
if (!all_ok)
{
puts("Please provide letters or numbers only");
}
else
{
puts("Success!");
}
return 0;
}

"Vigenere" : String lowercasing program is appending character for some inputs

I'm finding that my very basic code to lowercase a string is sometimes outputting an extra character. If I run vigenere with some inputs, it works correctly:
~/workspace/pset2/vigenere/ $ ./vigenere tweedDLed
tweeddled
But for other inputs, it inserts an extra character at the end:
~/workspace/pset2/vigenere/ $ ./vigenere tweedDLedf
tweeddledfB
or...
~/workspace/pset2/vigenere/ $ ./vigenere bkls33bf
bkls33bfW
What is going on here? I am not finding anything with the debugger as the character array is not displayed. This is my code:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <cs50.h>
int main(int argc, string argv[]){
if (argc!=2){
return 1;
}
else{
int n = strlen(argv[1]);
char cipherKey[n];
for (int i=0;i<n;i++){
cipherKey[i]=tolower(argv[1][i]);
}
printf("%s\n",cipherKey);
}
}
You need to allocate space for the string termination character, and you need to terminate your string. Otherwise, you leave your string unterminated, printf may read out of the string's bounds yielding undefined behaviour (e.g. in form of "weired" output). You could correct this as follows:
int n = strlen(argv[1]);
char cipherKey[n+1];
for (int i=0;i<n;i++){
cipherKey[i]=tolower((unsigned char)argv[1][i]);
}
cipherKey[n]='\0';

Error when using inputting string containing parenthesis as command line argument

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Incorrect command line arguments.\n");
return 0;
}
for (int i = 0; i < strlen(argv[1]);i++){
printf("%c",argv[1][i]);
}
printf("\n");
}
I have this simple code, however after compiling this is my output:
./a.out 123
123
./a.out (1+2+3)
bash: syntax error near unexpected token `1+2+3'
What is the reason this is happening, and how can I fix it? it seems like its the parenthesis which is messing this up. Thanks
The () characters have special meaning to bash. Use quotes to force bash to treat them as ordinary characters:
./a.out '(1+2+3)'

Resources