windows mingw asterisk '*' passing by argv[1] to string - c

I wrote a code below
#include<stdio.h>
int main(int argc, char *argv[]) {
char cmd[50]="dir";
if (argc == 2) {
sprintf(cmd,"dir %s",argv[1]);
}
if (argc == 3) {
sprintf(cmd,"dir %s %s", argv[1], argv[2]);
}
printf("%s\n",cmd);
system(cmd);
return 0;
}
when I executed like below
I think can't pass '*' by *argv[]
How can I pass something like "*.c" ?
update
code
#include<stdio.h>
int main(int argc, char *argv[]) {
char cmd[50]="dir";
if (argc == 2) {
sprintf(cmd,"dir %s",argv[1]);
}
if (argc == 3) {
sprintf(cmd,"dir %s %s", argv[1], argv[2]);
}
if (argc > 3) {
sprintf(cmd,"dir %s %s", argv[1], argv[2]);
}
printf("%s\n",cmd);
system(cmd);
return 0;
}
changing is below
what..... #.# ?
Updated code again
#include<stdio.h>
#include<string.h>
int main(int argc, char *argv[]) {
int i;
char sp[2]=" ", cmd[250]="dir";
if (argc > 1) {
sprintf(cmd,"dir /d ");
for (i =1 ; i < argc; i ++) {
strcat(cmd,sp);
strcat(cmd,argv[i]);
}
}
printf("%s\n",cmd);
system(cmd);
return 0;
}
see what happen when I executed
kind of ugly.... any decent idea?

This issue is not related to the C runtime, but to the shell behaviour. If you use Windows CMD.EXE, the * is passed unchanged to the programs, whereas if you use Cygwin's bash, the shell expands * to the list of files and passes this expansion as individual arguments to your program. You can prevent this expansion by quoting the wildcards with "*" or '*'.
Note that you should not use sprintf, but snprintf to avoid buffer overflows. If you link to the non standard Microsoft C library, you may need to use _snprintf instead.
EDIT: CMD.EXE does not seem to expand wildcards, but the C runtime you link your program with might do it at startup. See this question: Gnuwin32 find.exe expands wildcard before performing search
The solution is to quote the argument.

I'm afraid the accepted answer is not correct as the edit courteously admits. What is happening here is that globbing behaviour is provided in the C runtime but the default behaviour differs between compilers.
Yes, it's a major pain if you do not know what is happening. Worse the globbing does not occur if the glob does not match any files. I was pretty surprised myself.
Under Visual Studio, by default, wildcards are not expanded in command-line arguments. You can enable this feature by linking with setargv.obj or wsetargv.obj:
cl example.c /link setargv.obj
Under MinGW, by default, wildcards are expanded in command line arguments. To prevent this you can link with CRT_noglob.o or, much more easily, add the global variable:
int _CRT_glob = 0;
in your own source in the file which defines main() or WinMain().

Related

Print command line parameter on console

I want to pass a file name to my programm. If I type it in the terminal it works. But if I pass it as a command line parameter it doesn`t print the string in the end. Just something like: "²☺"
Any ideas why?
#include <stdio.h>
int main(int argc, char* argv[]){
char *nameDatei[100];
if(argv[1] != NULL) {
nameDatei[100] = argv[1];
} else {
printf("type in the name of the file: ");
scanf("%s", nameDatei);
}
printf("%s", &nameDatei);
return 0;
}
It only works "by accident" when you type the name at the terminal, and that's because you are either ignoring compiler warnings or using an obsolete compiler (any compiler which is not complaining about the code is obsolescent, though GCC 11.2.0 seems to accept it unless you pass warning options such as -Wall -Wextra -Werror).
You pass a char *(*)[100] to printf() but tell it that the argument is a char *
You pass a char ** to scanf() but tell it that the argument is a char *
You try to access element 100 of an array of size 100, which is one too many.
You happen to have 100 * sizeof(char *) bytes to hold the name, which is where the accident comes in, but that's not the correct type.
You need code more like:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *nameDatei;
char nameBuffer[100];
if (argv[1] != NULL)
nameDatei = argv[1];
else
{
printf("type in the name of the file: ");
if (scanf("%99s", nameBuffer) != 1)
{
fprintf(stderr, "failed to read file name\n");
exit(EXIT_FAILURE);
}
nameDatei = nameBuffer;
}
printf("%s\n", nameDatei);
return 0;
}
I called the source cla61.c and the program cla61. A couple of sample runs:
$ cla61 abyssinian-coffee
abyssinian-coffee
$ cla61
type in the name of the file: abyssinian-coffee
abyssinian-coffee
$
Don't copy command-line arguments unless you are going to modify them. But it's legitimate to make a new variable point to a command-line argument. And when there isn't a command-line argument, you need to allocate space for the replacement value — the value read from the terminal in this example.

What is ./nqt in C programming and how do i change file without changing them in the code

So i trying to input multiple files in the assigned program.
My input file code is as such:
int read_File(int *hp, int *d, int *s, char t[])
{
FILE *infile;
infile = fopen("input1.txt", "r");
if (!infile)
{
return 0;
}
else
{
fscanf(infile, "%d", hp);
fscanf(infile, "%d", d);
fscanf(infile, "%d", s);
fscanf(infile, "%s", t);
fclose(infile);
return 1;
}
i did
$>gcc assignedProgram.c -o nqt
$>./nqt input1.txt
but if i want to read input2.txt, i have to change from input1.txt to input2.txt in the codes. Is there anyway to bypass that and read input2.txt without changing from input1.txt to input2.txt in the codes
like when i tried ./nqt input1.txt => it's normal
BUT ./nqt input2.txt it's segmentation fault:11
I tried:
to change "input1.txt" in the codes to "nqt" but that was a dumb idea
and BTW: what is ./nqt
Please help me!
You must write main() as one of the equivalent forms below
int main(int argc, char **argv) { /*...*/ }
int main(int argc, char *argv[]) { /*...*/ }
so that argc and argv are set up by your environment to proper values.
For example
$ ./nqt input.txt
^^^^^ ^^^^^^^^^ --> 1
\\\\\-------------> 0
Translates in your program to
argc == 2
argv[0] ==> pointer to "./nqt"
argv[1] ==> pointer to "input.txt"
argv[2] ==> NULL
When it comes to nqt, it is the name of the program you specified with -o flag when compiling: gcc assignedProgram.c -o nqt. In order to run the program, you need to use ./ prefix, thus ./nqt means "run the program called nqt".
If you want to pass the name of the file as an argument, you should tell main function to accept command line arguments: int argc and char* argv[] (you can read about it here). Then the name of the file you will pass by running ./nqt <filename> would be stored in argv[1], which you should pass to read_File function as an argument.

command line arguments not working on visual c++ express 2010

I am having an issue passing command line arguments to my program using Visual C++ Express 2010. I found the command arguments under debugging and using the following input, just the terms with white space between them. The file is in my project folder with the .c source code.
TestFile1.txt 2
The program works fine when I just statically define the char pointer under main. So at this point I'm not sure if the issue is with 2010 or the code. I haven't figured out a way to compile and execute in some other way to test command line args. It would be great if someone could compile this an see if it works on their system.
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 256
int main(char *argv[])
{
//char *argv[] = { "program", "TestFile1.txt", "2" };
char buf[BUFFER_SIZE];
FILE *inFp;
printf("%s",argv[1]);
if ((inFp = fopen (argv[1], "r")) == NULL)
{
fprintf(stderr, "Can't open file\n");
exit(EXIT_FAILURE);
}
fclose(inFp);
return 0;
}
it should be int main(int argc, char *argv[]) Other than that, I have not seen any other problem with your program.

Command line execution of C program

I have a written a C program using Visual Studio 2008. The program compares to files in binary mode and tells us if the files are same or different.
I need to execute this program on command line and need to pass 2 arguments along with it.
the first argument is for the file to be compared and 2nd is the file to which it will be compared.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
int result_code;
char command_line[256];
sprintf(command_line, "FC /B %s %s > NUL:", argv[1], argv[2]);
result_code=system(command_line);
printf("%s file.\n", result_code ? "different" : "same");
return 0;
}
See this.
http://www.cprogramming.com/tutorial/print/lesson14.html
you can get plenty more from google.

Reading command line parameters

I have made little program for computing pi (π) as an integral. Now I am facing a question how to extend it to compute an integral, which will be given as an extra parameter when starting an application. How do I deal with such a parameter in a program?
When you write your main function, you typically see one of two definitions:
int main(void)
int main(int argc, char **argv)
The second form will allow you to access the command line arguments passed to the program, and the number of arguments specified (arguments are separated by spaces).
The arguments to main are:
int argc - the number of arguments passed into your program when it was run. It is at least 1.
char **argv - this is a pointer-to-char *. It can alternatively be this: char *argv[], which means 'array of char *'. This is an array of C-style-string pointers.
Basic Example
For example, you could do this to print out the arguments passed to your C program:
#include <stdio.h>
int main(int argc, char **argv)
{
for (int i = 0; i < argc; ++i)
{
printf("argv[%d]: %s\n", i, argv[i]);
}
}
I'm using GCC 4.5 to compile a file I called args.c. It'll compile and build a default a.out executable.
[birryree#lilun c_code]$ gcc -std=c99 args.c
Now run it...
[birryree#lilun c_code]$ ./a.out hello there
argv[0]: ./a.out
argv[1]: hello
argv[2]: there
So you can see that in argv, argv[0] is the name of the program you ran (this is not standards-defined behavior, but is common. Your arguments start at argv[1] and beyond.
So basically, if you wanted a single parameter, you could say...
./myprogram integral
A Simple Case for You
And you could check if argv[1] was integral, maybe like strcmp("integral", argv[1]) == 0.
So in your code...
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc < 2) // no arguments were passed
{
// do something
}
if (strcmp("integral", argv[1]) == 0)
{
runIntegral(...); //or something
}
else
{
// do something else.
}
}
Better command line parsing
Of course, this was all very rudimentary, and as your program gets more complex, you'll likely want more advanced command line handling. For that, you could use a library like GNU getopt.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int i, parameter = 0;
if (argc >= 2) {
/* there is 1 parameter (or more) in the command line used */
/* argv[0] may point to the program name */
/* argv[1] points to the 1st parameter */
/* argv[argc] is NULL */
parameter = atoi(argv[1]); /* better to use strtol */
if (parameter > 0) {
for (i = 0; i < parameter; i++) printf("%d ", i);
} else {
fprintf(stderr, "Please use a positive integer.\n");
}
}
return 0;
}
Parsing command line arguments in a primitive way as explained in the above answers is reasonable as long as the number of parameters that you need to deal with is not too much.
I strongly suggest you to use an industrial strength library for handling the command line arguments.
This will make your code more professional.
Such a library for C++ is available in the following website. I have used this library in many of my projects, hence I can confidently say that this one of the easiest yet useful library for command line argument parsing. Besides, since it is just a template library, it is easier to import into your project.
http://tclap.sourceforge.net/
A similar library is available for C as well.
http://argtable.sourceforge.net/
There's also a C standard built-in library to get command line arguments: getopt
You can check it on Wikipedia or in Argument-parsing helpers for C/Unix.

Resources