Using an if/else statment to check that enum arguments exist - c

I'm having a slight issue with my current piece of code and trying to check that arguments have been passed to enum before trying to continue with the program;
enum arg {argName, sineArg, sampleArg, argC}eargs;
int main(int argc, char *argv[]){
long samplingRate = atol(argv[sampleArg]);
float sineFreq = atof(argv[sineArg]);
if (argC < eargs ){
printf("Usage: sineFreq\tsamplingRate\n");
}else{}
}
The code compiles fine, although when run without arguments the program returns "Segmentation fault: 11" instead of the usage message that I want to print to console.

you have to do the check before accessing argv[...]
EDIT: the check itself is wrong too (eargs is undefined; you should write
int main(int argc, char *argv[]) {
if (argc < argC) /* --> you should change you naming conventions! */
return EXIT_FAILURE;
long samplingRate = atol(argv[sampleArg]);

Your usage check is against eargs that has nothing to with the number of command line arguments passed. No matter how many arguments you pass, eargs is always going to be 0.
Also you should do the check before using any of the command line arguments. Place the condition at the start of main():
#include<stdio.h>
#include <stdlib.h>
enum arg {argName, sineArg, sampleArg, argC}eargs;
int main(int argc, char *argv[]) {
/* if ( argc < 3) would be explicit and clear here */
if (argc < argC ) { /* You expect at least two arguments */
printf("Usage: sineFreq\tsamplingRate\n");
return 1; // return from main on failure
}
long samplingRate = atol(argv[sampleArg]);
float sineFreq = atof(argv[sineArg]);
....
}
I have also included standard headers as you are using printf() and atol()

you need to change argC to argc, in the if statement...c is case-sensitive!!!

When you run the code without arguments, this
long samplingRate = atol(argv[sampleArg]);
accesses argv[2], which is undefined behavior, since you don't provide enough args (there are only argv[0] = program name and argv[1] = NULL indicating the end of the argv[]).

Related

Can't seem to get the argc correct (cs50 problem set 2 )

#include <stdio.h>
#include <string.h>
int main(int argc, char **argv[])
{
if (argc != 2)
{
printf("Incorrect number of arguments, try again");
return 1;
}
else{printf("Congrats\n");}
printf("argv is: %s",argv[1]);
}
The code is incomplete and the task is for me to receive an input from the user via command line argument and to encrypt it. However I cannot seem to get the correct comman line argument. For example if input is "ceaser.exe 2" where ceaser is the name of my executable file and 2 is my input, argv[1] shows as "2ceaser.execeaser.exe".
Have watched a lot of vids but seems like theres nothing wrong with the format of my code but can't seem to solve this issue. The output I want for argv[1] should be "2" but can't seem to get it.
You declared your main function incorrectly. argv should be of type char** or char*[], not char**[].
int main(int argc, char* argv[])

Getting an unexpected seg fault when creating a custom shell prompt

So the following snippet should either make the prompt in a simple shell program 'my257sh'>, or ''> if -p is used as a command line arg when launching, followed by a string to be used as the custom prompt.
The custom prompt works fine, but I get a seg fault when launching with no additional args.
Can someone tell me what incredibly simple and stupid thing I'm doing wrong?
int main(int argc, char *argv[]) {
char cmdline[MAXLINE]; /* Command line */
char def_prompt[20] = "my257sh";
const char prompt_check[2] = "-p";
char new_prompt[20];
if (argc > 0){
if (strstr(argv[1], prompt_check)) {
strcpy(new_prompt, argv[2]);
}
}
else {
strcpy(new_prompt, def_prompt);
}
signal(SIGINT, sigIntHandler); // ignores ctrl + C interrupt
while (1) {
/* Read */
printf("%s> ",new_prompt);
...
argc is always > 0 : argv[0] contains the name of the program.
Check
If argc > 1
Also in case of -p check that
If argc > 2
You also need to check the length of prompt to avoid copying in too small string
argc contains the number of arguments passed on the shell, including the command itself, so argc will always be > 0 as it is at least 1 if no parameters were given.
If you don't pass any arguments, then argv[1] will contain a NULLpointer. If you pass only one parameter then argv[2] is a NULL pointer.
if (argc > 2)
{
if (strstr(argv[1], prompt_check))
strcpy(new_prompt, argv[2]);
}
else
{
strcpy(new_prompt, def_prompt);
}

Extra string added during input system call in C

When I compile this using GCC on linux, as I am waiting for input, the "hi" shows up. I do not want to use scanf, and want to know why the hi is showing while I am asking the user to input the name. Also when I want to printout the name of the file that was just passed, I get garbage characters. In netbeans, i get what I want. but on linux, it decides to act weirdly. please help
Code:
int main(int argc, char** argv)
{
char val[70];
if(write(1, "Please input your name", 36)!=36)
{
return -1;
}
if(read(0, val, 36) < 0)
{}
if(write(1, val, 36)!=36)
{}
printf("Yo");//THIS IS PRINTING OUT WAY BEFORE IT IS CALLED, ANY VARIABLE WITH A STRING GETS PRINTED OUT, EVEN WITHOUT PRINTF BEING INVOKED
}
output:
Please input the file nameYo: hi
hi
???Om?0?a?Sm? <<WHAT IS THIS? I DONT GET THIS ON NETBEANS
The third argument to write is the byte length of the string you're trying to print. You have 36, but the string you provide is only 22 bytes long. Changing the code to look like the following will behave as you expected it to:
int main(int argc, char** argv)
{
char val[70];
if(write(1, "Please input your name", 22)!=22)
{
return -1;
}
if(read(0, val, 36) < 0)
{}
if(write(1, val, 36)!=36)
{}
printf("Yo");//THIS IS PRINTING OUT WAY BEFORE IT IS CALLED, ANY VARIABLE WITH A STRING GETS PRINTED OUT, EVEN WITHOUT PRINTF BEING INVOKED
}
Note that you should probably look into using printf and scanf so that you wont have to worry about byte lengths so much.
That might look like this:
#include <stdio.h>
int main(int argc, char** argv)
{
char val[70];
printf("Please input your name");
if(scanf("%69s", &val) == 1)
printf(val);
printf("Yo");
}

How to run c program and give input in same line

I'm new to C and I'd like to ask about running a C program and supplying input at the same time.
What I would like to do is run a program (ex. fileOpener) and also state which file to open
./fileOpener < filename1
I've tried it already and it works fine, but what do I use to know what filename1 is? That way I can open the file with
fp = fopen(filename1, "r")
Thanks.
Edit: OK, I'll try to explain a bit more. If there wasn't a "<" then I could just use command line arguments as I have done before, but when I tried it with the <, it didn't work
Specifically: fileOpener code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
printf("%s", argv[1]);
}
when I use ./fileOpener < filename1 the output is ./fileOpener
I used gcc -o fileOpener fileOpener.c as the compiler
int main(int argc, char *argv[])
You can name them whatever you want, but these are the normal names.
argc is non-negative. It gives the number of useful elements in argv.
If argc is positive, argv[0] contains the program name. Then argv[1] through argv[argc - 1] point to character arrays that contain the program's command line arguments.
For example, if I run a program at the command line, such as
unzip filename.zip
argc will equal 2; and argv[0] will compare equal to "unzip"; and argv[1] will compare equal to "filename.zip".
Source
You can't do that, if you use redirection (i.e. "< filename") the file is opened by the system. You could discover the name, but it's non-portable, and anyway useless since the file is already open. Just use stdin instead of fp, and you need not use fopen() (nor fclose()):
int main()
{
char buffer[1024];
// fgets() reads at most 1024 characters unless it hits a newline first
// STDIN has been already opened by the system, and assigned to data flowing
// in from our file ( < inputFile ).
fgets(buffer, 1024, stdin);
printf("The first line of input was: %s", buffer);
}
A different approach is to use arguments:
int main(int argc, char **argv)
{
FILE *fp = NULL;
char buffer[1024];
if (argc != 2)
{
fprintf(stderr, "You need to specify one argument, and only one\n");
fprintf(stderr, "Example: %s filename\n", argv[0]);
// Except that argv[0], this program's name, counts.
// So 1 argument in command line means argc = 2.
return -1;
}
printf("I am %s. You wanted to open %s\n", argv[0], argv[1]);
fp = fopen(argv[1], "r");
fgets(buffer, 1024, stdin);
printf("The first line of input was: %s", buffer);
fclose(fp); fp = NULL; // paranoid check
return 0;
}
You need setup your program to take a command line argument. Here's a good tutorial that solves your exact question:
http://www.cprogramming.com/tutorial/c/lesson14.html
A program's main function in C has two arguments:
int main(int nArgs, char *pszArgs[]) {}
That first argument tells the program how many parameters were passed onto the program when you ran it. Usually, this will just be 1, because it includes the program's name.
The second argument is a table of strings, which can be accessed thus (the program below prints the parameters given to it):
int main(int nArgs, char *pszArgs[])
{
int i = 0;
while (i < nArgs)
{
printf("param %d: %s\n", i, pszArgs[i]);
i++;
}
return 0;
}

how number of thread should be accepted via command line using pthread?

I am writting an application that has multiple threads in Linux environment using C or python. I am using pthread for that. But How number of threads should be accepted via command line.
In C you handle command line arguments by having main take two arguments,
int main(int argc, char** argv)
in which argc is the number of command line arguments (including the program itself) and argv is a pointer to a memory location where argc-1 pointers to strings with the actual arguments are located. Example:
int main(int argc, char** argv)
{
printf("The program was executed as %s.\n", argv[0]);
printf("The arguments were:\n");
for (int i = 1; i < argc; i++)
printf("%s\n", argv[i]);
return 0;
}
Let's now assume that your program takes a single command line argument, an integer telling you how many threads to spawn. The integer is given as a string, so we have to convert it using atoi:
if (argc != 2)
{
printf("Need exactly one argument!\n");
return 1;
}
int num_threads = atoi(argv[1]); // Convert first argument to integer.
if (num_threads < 1)
{
printf("I'll spawn no less than 1 thread!\n");
return 2;
}
Now what you do is simply create an array of thread handles,
pthread_t* threads = malloc(num_threads*sizeof(pthread_t));
and use it to store the thread handles as you start num_threads number of threads using pthread_create.
If you are not familiar with pthreads at all, I recommend this short tutorial.
If you were using a threading framework like OpenMP, then this is all handled automatically simply by setting the environment variable OMP_NUM_THREADS.
But if you're implementing threads "manually", you'll need to do it the way most runtime configuration is done: either by parsing argv[], or by setting an environment variable and using getenv().
Usually, you would just pass it like any other argument. I've used code similar to the following in projects before to specify fixed thread counts. This is fairly simple but suitable for situations where you don't need the full power of thread pooling (though you could just as easily set a minimum and maximum thread count the same way).
#include <stdio.h>
#define THRD_DFLT 5
#define THRD_MIN 2
#define THRD_MAX 20
static int numThreads = 0;
int main (int argCount, char *argVal[]) {
if (argCount > 1)
numThreads = atoi (argVal[1]);
if ((numThreads < 5) || (numThreads > THRD_MAX)) {
printf ("Number of threads outside range %d-%d, using %d\n",
THRD_MIN, THRD_MAX, THRD_DFLT);
numThreads = THRD_DFLT;
}
:
:

Resources