I have to process command line input and if one of the arguments equal to "-?", I have to write an explanation of what I am making
here is what my code looks like:
#include <stdio.h>
#include <string.h>
#include "header.h"
#define ul unsigned long
int main(int argc, char *argv[]){
for(int i = 0; i < argc; i++){
printf("%s\n", argv[i]);
}
if(argc > 1){
if(strcmp(argv[1], "-?") == 0){
printf("Here I compare 2 strings using my prototype of strcmp(). You have to pass .\\a.out and 2 strings you want to compare.\nIf you want to see their length, type -v after passing values of strings:)\n");
}
}
if(argc > 3){
if(strcmp(argv[3], "-v") == 0){
printf("The length of the 1st string: %lu\nThe length of the 2nd string: %lu\n", strlen(argv[1]), strlen(argv[2]));
}
}
char *s1 = argv[1];
char *s2 = argv[2];
printf("%i\n", strcmp1(s1, s2));
}
and this is what I get if I pass ./a.out -? :
zsh: no matches found: -?
So, my question is how do i process "-?"?
Related
#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.
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 + !.
I'm trying to write a program that finds the largest and smallest of 10 numbers.
To use my program, you must use the command line argument -l then numbers to determine largest number, the same for the command -s for smallest numbers.
However, when I don't enter a command at all, and just try to run the program, I receive a segmentation fault. Not sure where I went wrong.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
int i;
int min,max,num;
char *argv1 = argv[1];
char *small = "-s";
char *large = "-l";
min=max=0;
if (0==strcmp(argv1, small))
{
for (i=2; i<argc; i++)
{
num=atoi(argv[i]);
if(i==2)
{
min=num;
}
else
{
if(min>num)min=num;
}
}
printf("The smallest number is %d\n",min);
}
else if (0==strcmp(argv1, large))
{
for (i=2; i<argc; i++)
{
num=atoi(argv[i]);
if(i==2)
{
max=num;
}
else
{
if(max<num)max=num;
}
}
printf("The largest number is %d\n",max);
}
else
{
printf("Invalid option");
}
return 0;
}
Check the number of arguments before accessing to arguments.
int main(int argc, char* argv[])
{
int i;
int min,max,num;
char *argv1 = argv[1];
char *small = "-s";
char *large = "-l";
/* add from here */
if(argc < 2)
{
fprintf(stderr, "Usage: %s command numbers...\n", argc > 0 ? argv[0] : "");
return 1;
}
/* add until here */
min=max=0;
You're setting char *argv1 = argv[1]; without first checking argc to see how many arguments were passed. This will cause a segfault when you later do if (0==strcmp(argv1, small)) because argv1 isn't pointing at a string like you are expecting it to.
To fix it, just check argc before you start comparing argv1 with anything:
if (argc == 1)
{
printf("Error: -s or -l required\n");
exit(1);
}
Ok so what I have to do is input a binary number IN THE TERMINAL, probably using argv[] or something, and then break it into each digit.
What I have is this:
int bits[31];
for(int i=0; i<31 && 1 == fscanf(stdin, "%1d", &bits[i]); ++i);
This works for the scanf, but I would want a SIMPLE way of doing so but with the input being in the terminal
This code accepts a binary number as the program argument. Most of the code is devoted to weeding out any invalid argument.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int len;
long bin;
if (argc < 2) {
printf("Please try again with an argument supplied\n");
return 1;
}
len = strlen(argv[1]);
if (strspn(argv[1], "01") != len) {
printf("The argument is not a binary number\n");
return 1;
}
printf("First bit is %c\n", argv[1][0]);
printf("Last bit is %c\n", argv[1][len-1]);
bin = strtol(argv[1], NULL, 2);
printf("As a long integer variable, the input is %ld\n", bin);
return 0;
}
Without error checking (except against crashing), this reduces to
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int len;
if (argc > 1) {
len = strlen(argv[1]);
printf("First bit is %c\n", argv[1][0]);
printf("Last bit is %c\n", argv[1][len-1]);
printf("As a long integer the input is %ld\n", strtol(argv[1], NULL, 2));
}
return 0;
}
I'm working on a C program that get the command line arguments and append to them a file extension.
The execution will be something like this:
>myprogram file1 file2
and will execute another program that will use as argument file1.txt and file2.txt.
I tried doing that would add the extension and run one command (s1 is the path and s2 is argv[i] on a loop:
int getfile(char *s1, char *s2){
char *str2 = malloc(sizeof(s2)+3);
strcpy(str2,s2);
strcat(str2,".txt");
execl(s1,"program",str2,NULL);
exit(0);
}
The function will run the program for one file (>program file1.txt and >program file2.txt), but I will need to find a way to run it this way (>program file1.txt file2.txt).
I tried to modify argv directly, but I was unsuccessful.
Any advise?
Try this code:
int main(int argc, char *argv[])
{
char *buffer;
char command[512];
int i = 1;
for(i = 1; i < argc; i++){
buffer = malloc(strlen(argv[i]) + 5);
strcpy(buffer,argv[i]);
strcat(buffer,".txt");
sprintf(command,"touch %s\0",buffer);
system(command);
free(buffer);
}
return 0;
}
A simple program that has no error checking, and I like to explicitly add the string terminator.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, int *argv[]){
if(argc==1){
printf("You have not entered anything!\n");
return 0;
}
char *arr=malloc(1000*sizeof(char));
int i;
strcat(arr, argv[0]);
strcat(arr, " ");
for(i=0;i<argc-1;i++){
strcat(arr,argv[i+1]);
strcat(arr,".txt");
strcat(arr," ");
strcat(arr,"\0");
}
printf("%s\n",arr);
free(arr);
return 0;
}