How to valid 2 sticked argc in C - 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.

Related

How to solve segmentation fault in 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]).

How I can cause a program in C to print only one statement once it encounters a specific condition?

I have been trying to write a C program where the user inputs a command-line argument and the program checks if it is all number digits or not. If that is true, the program simply reprints what the user put in. If that is false and there is at least one non-number mixed in, the program just prints the word "bad" once.
What I have come up so far consists of the program checking each character of the input individually. However, what ends up happening once I put in a mixture of numbers and letters in is that the program would still print the numbers, and then once it gets to printing a letter, it prints the word "bad".
Here's an example:
I put ./program 100x into the terminal
=> Expected result: bad
=> Actual result: 100bad
Here's the code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, string argv[])
{
for(int i = 0; i < strlen(argv[1]); i++) {
if (isdigit(argv[1][i]) != 0) {
printf("%c", argv[1][i]);
return 0;
} else {
printf("bad");
return 1;
}
}
}
First, I don't think your program is doing what your describe because it returns at the first digit encountered. Then, as soon as you see a digit you print it, you want to first check that your input is right and then print it. Taking your implementation, you could modify it like that:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, string argv[])
{
// checking input
for(int i = 0; i < strlen(argv[1]); i++) {
if (!(isdigit(argv[1][i]) != 0)) {
printf("bad\n");
return 1;
}
}
// here you know your input is good
// prints input
printf("%s\n", argv[1]);
return 0;
}
Try this one :
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
//for(int i = 0; i < strlen(argv[1]); i++)
{
//if (isdigit(argv[1][i]) != 0)
if(strspn(argv[1], "0123456789" )== strlen(argv[1]))
{
printf("%s", argv[1]);
return 0;
}
else
{
printf("bad");
return 1;
}
}
}
Your logical error is that your program checks one character and immediately prints a digit or a bad message, and so continues with each character. However, you need to try writing an algorithm that first checks the whole string for characters other than numbers. If the algorithm finds at least one character (the result is false), it can close loop by using "break" keyword and print "bad" after. OR if all characters are numbers, you can return the value true and only then print them on the screen.

How to check if command line parameters are integers

First of all, I am talking about old-fashioned ANSI-C (I mean the ANSI standard and no C99 or newer) compiled with gcc. I am only allowed to use the libraries that can be seen below in the code.
My problem is I have a program that is called in the following way on the Terminal:
program < integer_1 integer_2
While I have been able to figure out how to check for the number of arguments, I'm stuck on checking if those are integers.
If the program is called like this:
program < 1 -13
it should run without complaining but if it is run like this:
program < s 7
it should throw out an error.
Whatever I have tried so far has been utter rubbish. The best thing I have managed so far has been an error message if the second number has been a character. None of my tries has been able to deal with more than one digit but I have figured out why that is.
The problem is that I haven't used command line / terminal arguments with any programming language i now (C++, Java). I would really appreciate it if someone could show me how check for correct input as frankly I am out of ideas.
Am I correct that if I want to deal with numbers bigger than 9, I have to iterate through argv starting from index 2 until I find a space?
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(int arc, char *argv[])
{
if(arc != 3)
{
printf("Error: You have entered %d arguments, but two were expected!", arc - 1);
return -1;
}
return 0;
}
The easiest way out is to iterate over the argv[n]s and pass one by one to them to strtol() or similar. Then, check for the error and make the decision. To quote the man page, (emphasis mine)
long int strtol(const char *nptr, char **endptr, int base);
[...]
If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, strtol() stores the original value of nptr in *endptr (and returns 0). In particular, if *nptr is not '\0' but **endptr is '\0' on return, the entire string is valid.
That said, program < integer_1 integer_2 is not exactly the way to pass the command-line arguments. If you want to pass the values arguments as command-line arguments, you shall lose the redirection operator and work with argc and argv[n]s directly..
Best way is to create a function for checking whether it is number or not.if the below function returns true then use atoi(argv[]) to convert them to integers to use it further.
bool isNumber(char number[])
{
int i = 0;
//checking for negative numbers
if (number[0] == '-')
i = 1;
for (; number[i] != 0; i++)
{
//if (number[i] > '9' || number[i] < '0')
if (!isdigit(number[i]))
return false;
}
return true;
}
Just a comment: not an answer
If you are going to use
program < arg1 arg2
You will not see arg1 or arg2 in the main parameters. arg1 is typically a filename or device which contain data which will be read by the program. I don't know if the program will even be able to access arg2. If you wish to pick up arg1 arg2 etc, lose the <
program arg1 arg2
You can try something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int check_cmd_args(char const *str[], int numargs);
int
main(int argc, char const *argv[]) {
if (argc < 2) {
printf("Not enough command line arguements entered\n");
exit(EXIT_FAILURE);
}
if (check_cmd_args(argv, argc)) {
printf("All Command line arguements are integers\n");
} else {
printf("Error, non-integer command line arguement entered\n");
}
return 0;
}
int
check_cmd_args(char const *str[], int numargs) {
int n, i = 0;
for (n = 1; n < numargs; n++) {
if (str[n][0] == '-') {
i = 1;
}
for (; str[n][i]; i++) {
if (!isdigit(str[n][i])) {
return 0;
}
}
}
return 1;
}

String bug in my_shell program

I'm trying to create a simple shell program which execute the program specified in input. There are two main function: scanner() (use strtok to split the input in token) and execute() (fork the process and execute the program).
Unfortunately it doesn't work... I've tried to print string[0] at the end of scanner() and at the beginning of execute(). The first time the output is correct but the second time string[] seems to be modified in a sequence of random numbers so execvp() doesn't work...
I really can't figure out why the values of string[] changes, probably is a very stupid error but I can't see it. I really need your help! Thanks in advice.
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#define DIM 256
int scanner(char*[]);
int execute(char*[]);
int main()
{
char* string[DIM];
scanner(string);
execute(string);
}
/* scan: read the input in token*/
int scanner(char* string[])
{
char input[1024];
char delimit[]=" \t\r\n\v\f";
int i = 0;
if(fgets(input, sizeof input, stdin)) {
string[i] = strtok(input, delimit);
while(string[i]!=NULL){
i++;
string[i]=strtok(NULL,delimit);
}
return 0;
}
return 1;
}
/* execute: execute the command*/
int execute(char* string[])
{
int pid;
printf("%s\n", string[0]);
switch(pid = fork()){
case -1:
return 1;
case 0:
execvp(string[0], string);
return 1;
default:
wait((int*)0);
return 0;
}
}
The string variable input in scanner is a local variable, with storage class "auto". That means that when that function returns, that variable disappears, and the memory it occupied can be re-used for other things. That is unfortunate, since strtok returns pointers into that string variable.

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.

Resources