How to solve segmentation fault in c? - c

When I was making my program I got an error type of thing called Segmentation Fault.
#include <cs50.h>
#include <string.h>
#include <stdio.h>
int main(int argc, string argv[])
{
char i = strlen(argv[2]);
if (argc == 2)
{
printf("%i %s %hhd", argc, argv[2], i);
}
}
I run this program using these commands
make substitution
and then
./substitution abcdefghijklmnopqrstuvwxyz
In this we have to add a 26 word key which in the above line is a to z.
Please help if you know to solve

If you invoke your program with:
./substitution abcdefghijklmnopqrstuvwxyz
argc will be 2, and argv will be an array of 3 pointers:
argv[0] points to the string ./substitution, argv[1] points to the string abcdefghijklmnopqrstuvwxyz, and argv[2] is NULL. If you attempt to compute the length of NULL by calling strlen(argv[2]), that is an error. You must not pass NULL to strlen. I think your error is simply mis-indexing the argv array. Arrays in C are zero based. If you want to compute the length of the first argument, you want to work with argv[1], not argv[2]:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int rc = EXIT_FAILURE;
if( argc > 1 ){
size_t i = strlen(argv[1]);
printf("%i %s %zd\n", argc, argv[1], i);
rc = EXIT_SUCCESS;
}
return rc;
}

You got hit with segfault because the number of required arguments specified was done poorly. The main problem is here:
if (argc == 2)
The number of actual arguments passed by the user is equal to the number of required arguments minus 11. It should be:
int main(int argc, char *argv[]) {
if (argc != 3) {
// Number of arguments are either greater or lesser than 3
// Handle the error
}
// Ok...
}
You can safely use the arguments now.
1. The calling command for the program, for example ./a.out is also counted as an argument (argv[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 to valid 2 sticked argc in C

I'm making a very simple program code.
First, it has the option "-num" as 2nd argc. If you input anything in the 3rd argc, the program will simply say that the 3rd argc is entered.
Here are the examples of the inputs and outputs.
Input command line 1:
./test -num
Output 1
-num
Input command line 2:
./test -num AnythingHere
Output 2
-num 3rdArgcEntered
I also want the following command line with sticked argc (-num and AnythingHere are sticked together) to give the same output as Output 2:
./test -numAnythingHere
The output I wish to get is:
-num 3rdArgcEntered
But I obtained:
None
This is the source code I'm currently working on:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[])
{
if (!strcmp(argv[1], "-num"))
{
printf("-num ");
if(argc==3){
printf("3rdArgcEntered");
}
}
else
{
printf("None");
}
printf("\n");
return 0;
}
a little trash..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[])
{
/* doesnt check when args are not entered */
char *tmp = argv[1];
char buff[5];
/* copy -num, doesnt check */
memcpy(buff, tmp, 4);
buff[4] = '\0';
if (!strcmp(buff, "-num"))
{
printf("-num ");
/* larger than -num */
if(argc==3 || strlen(tmp) > 4 ){
printf("3rdArgcEntered");
}
}
else
{
printf("None");
}
printf("\n");
return 0;
}
Your program can't affect how the arguments are passed; obviously main has already been called at the beginning of main. You need to parse each argument yourself, or use a library that does it for you. For parsing them yourself, you could look at strtok or sscanf, or iterate over the characters. But a more specific library, such as getopt, is generally preferable, since it makes it easy to get your program to behave in a manner consistent with other command-line utilities.

C program with command line options

I wonder how to write a C program with options that can be invoked by a terminal.
Example : Person.c
#include <stdio.h>
void main ()
{
char option;
if(option == 'f') printf("First Name");
else if(option == 'l') printf("Last Name");
else printf("Full Name");
}
Compile it with
cc Person.c -o Person
Objective :
I want to reach my program options through terminal.
Example :
./Person -f
Output : First Name
void main () is wrong, if you copied this from a book, throw the book away
It should be int main(int argc, char **argv), argc will then be set to the number of arguments and argv[1] .... argv[argc-1] are the argument strings (argv[0] is the name of the program)
Here's my $0.02:
#include <stdio.h>
#include <string.h>
int
main (int argc, char *argv[])
{
if (argc != 2) {
printf ("USAGE: ./Person [-f|-l]\n");
return 1;
}
if (strcmp (argv[1], "-f") == 0) {
printf("First Name");
}
else if (strcmp (argv[1], "-l") == 0)
printf("Last Name");
}
else {
printf ("Unknown argument\n");
return 1;
}
return 0;
}
Important points:
1) In C, you can't just compare strings (like "aaa" == "bbb"). You need special library functions, like "strcmp()" ("compare strings").
2) In order to use library functions, you need to #include headers (like "stdio.h", for "printf()", or "string.h", for "strcmp()"). You can find out which headers you need by using "man" ... or simply Googling for the relevant call ("google strcmp" should give you the same results as "man strcmp")
3) It's a good general convention to use the programs return values to indicate "success" or "failure". "0", by convention, usually means "success".
4) Finally, for your purposes, it's essential to use "argc" and "argv" to access your command line arguments.
5) The "if (argc != 2)" at the top insures that you've entered at least one command line argument (argument "0" is the name of the program itself). This is important because trying to read an argument you don't have ("trying to read off the end of the array") could cause a crash ;)
'Hope that helps!
Please change your main prototype as
int main(int argc, char *argv[])
The options as asked by you in your question can be passed using the input arguments to the main function as given above.
The argc parameter tells you how many inputs has been passed through terminal and the argv will provide you each input as an array of char *. Please note that the first input (argv[0]) will be by default the filename of the executable with full path and the rest of inputs will follow it.
http://www.cprogramming.com/tutorial/c/lesson14.html - This tutorial will also be of some help.
The correct form for a main function is:
int main(int argc, char **argv) {
}
Then argv holds your command line arguments:
int main(int argc, char **argv) {
for(int i = 0; i < argc; ++i) {
printf("arg %d is %s", i, argv[i]);
}
return 0; // indicates that the program completed successfully
}
Call main with these inputs:
int main ( int argc, char **argv)
argc is the number of args, and argv is an array of the command line arguments. Note that the first argument of argv is the program name.
you have to tell C that your giving it options
int main(int argc, char **argv)
argc is the number of arguments and argv is the argument you call
so then ./Person -f
you need to tell it
if (strncmp(argv[i],"-f",1) == 0) {
You should also look at some of the parsing libraries out there. Many people have written great libraries for parsing command line options so that you don't have to repeat all of the work of validating options. Most are pretty easy to use, as well.

function to read a string and get the length - C

I'm having issues writing a C function that reads a string from STDIN, and returns the length of said string... Suggestions?
So, simply use strlen from the C standard library:
#include <string.h>
So the strlen() function is available. You just need to pass a char pointer, and it will return the string length:
size_t length = strlen( myStr );
Note that size_t is an integral type.
By the way, if you don't know about this function, you should really dig into the C library, and lear about the basic functions it provides.
#include <stdio.h>
#include <stdlib.h> // not totally necessary just for EXIT_SUCCESS
#include <string.h>
int main(int argc, char* argv[]) {
// check number of params
if (argc != 2) {
// argv[0] is name of exe
printf("usage: %s string", argv[0]);
// check length of first command line parameter
} else {
// strlen does the counting work for you
unsigned int length = strlen(argv[1]);
printf("Length is %d\n", length);
}
return EXIT_SUCCESS;
}

Resources