C, Why there is a Segmentation fault (core dumped) - c

#include <cs50.h>
#include <stdio.h>
#include<ctype.h>
int main(int argc, string argv[])
{
int KEY;
if(isdigit(argv[1]))
{
KEY = (int)argv[1];
}
else
{
printf("Usage: ./caesar key");
}
printf("\n");
printf("%i\n",argc);
}
I can't find out the problem when I type the following
How do I fix it?

This is not a high-level language with various syntax sugar features.
Important Notes:
Conversion of const char * to int is not done by just type-casting it.
isdigit() works only for int (single characters), not const char * it will cause Undefined Behavior.
argc is the length of pointer array argv
string is not a valid type for main() function arguments, it should be int main(int argc, char const **argv) { }
Must check whether argv[1] even exists or not
Once you print the usage your program should exit
Any error message should be printed on stderr
Must Use return EXIT_SUCCESS;, which is defined in the header file stdlib.h, when exiting the application, or use return EXIT_FAILURE; if something goes wrong.
Final Code
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char const **argv)
{
if(argc == 1)
{
fprintf(stderr, "Usage: %s <KEY>", argv[0]);
return EXIT_FAILURE;
}
for(size_t i = 0; argv[1][i]; i++)
{
if(!isdigit(argv[1][i]))
{
fprintf(stderr, "expected only integer value\n");
return EXIT_FAILURE;
}
}
// we don't need to check whether `argv[1]` is all digit or not at this point
int KEY = strtod(argv[1], NULL);
printf("argc = %d\n", argc);
printf("KEY = %d\n", KEY);
return EXIT_SUCCESS;
}

Related

segmentation fault cs50 week 2

I am writing a program to encrypt plain text. It forces the user to input a number in the command line, when i convert the data type of the number from string to int using atoi the program gives me segmentaion fault. I am not able to understand why.
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main( int argc, string argv[])
{
//make sure the program was run by using just one command line argument
string x = argv[1];
if(argc !=2)
{
printf("Usage: ./caesar key\n");
}
else
{
int y = strlen( argv[1]);
//makeing sure the command line argument input is a digit
for( int i = 0; i < y; i++)
{
if( isdigit( x[i])==0)
{
printf( "Usage: ./caesar key\n");
}
return 1;
}
}
printf( " hello \n");
//convert argv[1] from string to an int
int user_key = atoi( argv[1]);
printf( "key = %i\n",user_key);
//promt user for plaintext
//for each charecter in plaintext
// rotate charecter if it is a letter
}

Why in C99 Xcode, an 'int' require a return on the end, but in Codeblocks not?

I got a code from my teacher in Codeblocks C99, but I'm using Xcode and I tried to run it but Xcode want me to put a return to the end of an int
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
void usage(char *prg) {
printf("String pointer demo, usage: %c <text>\n", prg);
}
int process(int argc, char *argv[])
{
int l = strlen1(argv[1]);
{
char *target = malloc(l);
if (!target)
return EXIT_FAILURE;
printf("Copy of %s is %s\n", argv[1], strcpy1(target, argv[1]));
}
strlen1(NULL);
strcpy1(NULL, NULL);
return 0; // it's failing here but codeblocks it worked
}
int main(int argc, char *argv[])
{
printf("String pointer demo\n");
if (argc == 1) {
usage(argv[0]);
return EXIT_SUCCESS;
}
return process(argc, argv);
}
why is this?

how to iterate through argv through command line and C

#include <stdio.h>
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: one file only", argv[0]);
return (1);
} else {
for(int i = 0; i < argc; i++) {
putchar(argv[i]);
}
}
}
Say I want to print the input it takes in, for instance
$ gcc -Wall fileabove.c
$ ./a.out abcdefghijlmn
abcdefghijlmn
Basically just prints out whatever text I put into it.
putchar(argv[i]);
is incorrect, because putchar expects a single character (type char), you are passing a pointer (char*). It should be
puts(argv[i]);
So the correct code:
#include <stdio.h>
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: one file only\n", argv[0]);
return 1;
}
// no need for the else
// you exit program anyway if argc != 2
// makes code more readable
puts(argv[1]);
return 0;
}
If you want to print character by character:
#include <stdio.h>
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: one file only\n", argv[0]);
return (1);
}
for(size_t i = 0; argv[1][i] != '\0'; ++i)
putchar(argv[1][i]);
putchar('\n');
return 0;
}
edit changed puts("") to putchar('\n') and removed strlen as Jonathan Leffler mentioned in the comments.
The argument array is always in the format of first index being the called program name and the subsequent index values being the parameters in order. Because you only want one argument to process, I have simplified your code as follows:
#include <stdio.h>
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "%s usage: one file only\n", argv[0]);
return 1;
} else {
printf("%s\n",argv[1]); //print only parameter and new line
}
return 0;
}
When the user doesn't specify one parameter, then the error pops up including the program name. When the parameter is specified, it is stored in the second index of the array (index 1) and in my code, I simply printed it out using printf.

Using argc and argv in Caesar cipher in C

So, I am trying to use argc and argv in Caesars cipher in order to execute the program with just [./ key ;string] (e.g. ./ 13 Caesar). I have tried in lots of ways, although I must admit I am really lost here. I was thinking I should just use main(void) and ask the input with fgets, but I still have some curiosity in: How could I make it work with “int main(int argc, char *argv[])?”. Any clues you can give me?
Thank you for your help. Here is the code with the current outputs:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
int key;
int result;
char str[60];
int k = 0;
printf("argc =%d\n", argc);
printf("argv =%d\n", argv);
printf("key =%d\n", key);
if (argc != 2)
{
printf("You didn't enter a key.\n");
return 1;
}
else
{
int k = key % 26;
printf("k =%d\n", k);
if (k == 0)
{
printf("Invalid key.\n");
return 1;
}
}
}
Output:
$ ./ceasar 13
argc =2
argv =-13216
key =0
k =0
Invalid key.
Edit: Tentative Answer
int main(int argc, char* argv[])
{
int i;
int key = atoi(argv[1]);
int result;
char str[60];
for (i = 0; i < argc; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
if (argc != 2)
{
printf("You didn't enter a key.\n");
return 1;
}
else
{
if (key == 0)
{
printf("Invalid key.\n");
return 1;
}
}
}
Printing argv with the "%d" specifier is undefined behavior, read printf()'s manual and use "%p".
On the other hand, if you want to print the string you should access the appropriate element with array notation. For example
printf("First Argument: %s\n", argv[1]);
this applies to all arguments, noting that argv[0] is the name of the executable as invoked in the command line.
You should also be careful before accessing argv[1] to check that argc > 2, and always check the current argument + !.

Reading string character by character in C

So I have a string passed into main function: int main(int argc, char* argv[])
I understand argc (which is 2 in this case), but don't understand how I can read argv[] character by character?
When I print argv[0] shouldn't that print the first character in the array of characters for that string?
Thanks
sample
#include <stdio.h>
int main(int argc, char *argv[]){
int i,j;
for(i=0; i<argc; ++i){
for(j=0; argv[i][j] != '\0'; ++j){
printf("(%c)", argv[i][j]);
}
printf("\n");
}
return 0;
}
One more example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[])
{
if(argc != 2)
{
//argv[0] is name of executable
printf("Usage: %s argument\n", argv[0]);
exit(1);
}
else
{
int i;
int length = strlen(argv[1]);
for(i=0;i<length;i++)
{
printf("%c",argv[1][i]);
}
printf("\n");
return 0;
}
}

Resources