The task at hand is to write a program that accepts arguments from the command line and convert them into USD.

For example, take command line argument Currency EU 350, and convert in into USD.

Now, please bear with me -- I may be phrasing this incorrectly, but how do I give arguments to the command line to begin with?

If you want to use arguments then you need to use main() with argc and **argv.

argc is the counter of how many arguments that are passed in to the program (it is 1 with no additional arguments passed because it passes it's own path by default).

argv is the "vector" that holds all the arguments passed.

In Windows to pass arguments you need to run the command line and type "start FILEPATH arg1 arg2". Or you can use "call" if you want to keep it in the existing window.

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

int main(int argc, char **argv)
{
	int i;
	for( i = 1; i < argc; i++ )
		printf("%s\n", argv[i]);

	printf("Press any key to continue...");
	getch();
	return 0;
}

If you want the argument to be converted to an integer then you can use the atoi() function.

argc is the counter of how many arguments that are passed in to the program (it is 1 with no additional arguments passed because it passes it's own path by default)

argc is allowed to be zero. Further, even if argc is greater than zero, argv[0] is not required to be more than an empty string. If it's not an empty string, argv[0] represents the "program name". "Program name" isn't otherwise defined by the standard, but two common interpretations are the executable file name (eg. "foo.exe"), and the full executable file path ("C:\my programs\foo.exe"). So beware making assumptions about argv[0] .

argv is the "vector" that holds all the arguments passed.

Also note that it's a NULL terminated array, so argv[argc] is guaranteed to be a null pointer. This can simplify traversing the arguments by removing the need for an index:

#include <stdio.h>

void show_args(char *argv[])
{
    while (*argv != NULL) {
        printf("'%s'\n", *argv);
        ++argv;
    }
}

int main(int argc, char *argv[])
{
    puts("Raw args:");
    show_args(argv);
    
    return 0;
}

A minor bit of trivia that comes in handy occasionally, such as when tokenizing an argument with strtok(), is that the arguments are modifiable arrays. Provided you're careful about buffer overflow, you can write to argv[i] for any i in the range of [0, argc). Obviously the null pointer at argv[argc] doesn't constitute an array, modifiable or not. ;)

In Windows to pass arguments you need to run the command line and type "start FILEPATH arg1 arg2". Or you can use "call" if you want to keep it in the existing window.

Most IDEs will also offer a debug option for passing command line arguments.

#include <conio.h>

...

getch();

I'd strongly recommend getting out of the habit of using conio.h for anything. Most of the time it's unnecessary, and it destroys portability. While you can do anything you want with your own programs, it's best to strive for maximally portable code when helping people here (unless they explicitly ask for something non-portable). Your code can easily be made portable by switching to getchar() and simply requiring Enter and instead of any key:

#include <stdio.h>

int main(int argc, char **argv)
{
    int i;
    
    for (i = 1; i < argc; i++)
        printf("%s\n", argv[i]);

    printf("Press [Enter] to continue...");
    getchar();
    
    return 0;
}

The only issue with this that getch() doesn't typically have would be dealing with extraneous characters. If there's already a newline sitting in the stream, the pause won't work. But if you follow best practice for input, that shouldn't happen.

If you want the argument to be converted to an integer then you can use the atoi() function.

Please forget that atoi() exists. It's second only to gets() in bugginess because unless you pre-validate the string to ensure that it's a valid integer, you'll invoke undefined behavior. There's also the problem of returning 0 on a failed conversion without the requirement that errno be set. This means you have no way of telling if a return value of 0 is an error or a successful conversion of "0".

strtol() is a much better alternative because you have more robust error handling opportunities.

Out of curiousity, are there any situations in which one should still include conio.h? I haven't had to use it yet, but want to know what it is for.

are there any situations in which one should still include conio.h?

If you use a compiler that supports conio.h, it can often be the simplest solution. For example, reading a key press with getch() or kbhit() is simpler than implementing the same behavior with Win32 or POSIX libraries. Since those operations are inherently non-portable, it's not as bad as the more common uses of conio.h:

#include <conio.h>

int main(void)
{
    clrscr(); /* Unnecessary and anti-social clearing of the screen on startup */

    ...
}
#include <conio.h>

int main(void)
{
    ...

    getch(); /* Pause at the end of the program */

    return 0;
}

An example of using conio.h properly would be reading a masked password:

#include <stdio.h>
#include <conio.h>

char *read_password(char *buf, size_t limit)
{
    size_t i = 0;
    int ch;
    
    while (i < limit - 1) {       
        int ch = getch();
        
        if (ch == '\r') {
            putchar('\n');
            fflush(stdout);
            break;
        }
        if (ch == '\b') {
            fputs("\b \b", stdout);
            fflush(stdout);
            
            if (i > 0)
                --i;
        }
        else {
            putchar('*');
            fflush(stdout);
            buf[i++] = (char)ch;
        }
    }
    
    if (limit > 0)
        buf[i] = '\0';
        
    return buf;
}

int main(int argc, char **argv)
{
    char buf[BUFSIZ];
    
    printf("'%s'\n", read_password(buf, sizeof buf));
    
    return 0;
}

Reading a character without echo and replacing it with a mask character is something that cannot be done portably, so some non-portable solution is necessary. Provided conio.h is available, getch() is the simplest solution to the best of my knowledge.

This article has been dead for over six months. Start a new discussion instead.