How do I make a program where the user can type the file names (input and output files) to which they want to read and write to, on standard input using scanf?
e.g when they run the program ./start filename1 filename2
(in C).
If they run the program this way:
./start filename1 filename2
The input and output filenames are passed to the main function in the argv array. No need and indeed no way to use scanf to retrieve them.
Begin by learning how to open a text file and how write text.
http://www.cplusplus.com/reference/cstdio/fopen/
After if you know that, you can take argument in the main function (argc, argv), that will give you information of the parameters entered in the command line
int main(int argc, char *argv[])
{
//arc : how many value are in the command line
//argv : array of string, string from each parameter in the command line
//argc = 3
//argv = {"./start", "filename1", "filename2"}
return 0;
}
After you can use scanf to get value from the user. And after each scanf you can write in the file. Don't forget to close the file at the end.
Related
I'm trying to input only one filename from command line. Then I want to use an If statement to compare the filename to 4 different names I'm expecting to see. If I don't get one of the 4 expected file names then I need to print it back to the user with what was inputted and then exit the program safely.
int main(int argc, char *argv[])
{
....
}
I've been trying a lot of different methods of getting this done, but I just can't figure it out. I was thinking maybe the way I take the input argument is wrong. Any help would be greatly appreciated.
-edit
I just want to be clear I don't want you to be a leech and solve the question I have for me. Just at least point me in the correct direction. I can't figure how to make a for loop work with the filename.
for(argv == "UnexpectedFile.csv"){
printf("this is an unexpected file: %c", argv[1]);
}
You could use strcmp() from string.h to compare strings like
strcmp(argv[1], "unexpectedfile.csv");
It returns 0 when the strings are equal.
If you have the 4 file names in as an array of strings, say expectedFile, do
for(i=0; i<4 && strcmp(argv[1], expectedFile[i])!=0; ++i);
If the value of i is the total number of file names (ie, 4) after this loop, argv[1] is an unexpected file.
Otherwise, value of i would be the index of the file name string in the expectedFile array.
The command line arguments are stored in the 2-dimensional char array argv.
argv[0] would be the name of the executed file. The arguments you give start only from argv[1] onwards.
argc will have the total number of command line arguments including the file name stored in argc. So if there are 'no' arguments, argc would be 1.
In your case the file name is the only argument, so argc would be 2.
You must check if argc is at least 2 before you access argv[1] to prevent the program from accessing argv[1] when it isn't there.
(You do not ask for complete code solution (and do not provide enough of your code for that). So here are the pointers in the right direction you want.)
The comparison you do with a simple pointer == pointer does not really compare the content of the strings. That is what e.g. strcmp () is for, as proposed by #user3629249.
And in order to print out what was given as commandline argument, you should use "%s\n".
And in order to set up a for loop, you will have to do the syntax right: for(init assignment; condition; step operation).
(If you need more help, you will have to provide more details on what behaviour you get and what you do not like about it. Currently your code looks more like compiler errors, which you did not quote, than a problem with the behaviour goal...)
write c program that accepts one command line argument (your first name) and prompts the user for user input (your last name), then print ""Welcome to operating systems, "" to the screen.
Can anyone help me with this question? I know its using something like this from the below, but I dunno how to print out the thing? Can anyone help by giving the full answer? Thanks in advance.
int main (int argc, int *argv[])
argc is an integer that represents the number of command line arguments passed in to the program. It is the argument count, hence the name. *argv[] (or **argv depending on developer preference) represents the actual arguments. The proper name for argv is argument vector, which makes sense if you're familiar with that particular data type.
The first argument passed in, argc = 1 is the program's name. Argc is always at least one because argv will always contain at a minimum the name of the program.
To answer your question, you need to pass in a second command-line argument, argc = 2, where argv[1] equals the user's first name. We can accomplish that like this:
int main(int argc, char** argv)
{
// This line will print out how many command line arguments were passed in.
// Remember that it will always be at least one because the name of the program
// counts as an argument.
printf("argc: %d", argc);
// Remember that you want the second argument in argv,
// so you have to call argv[1] because arrays in C
// are 0-index based. Think of them as offsets.
printf("\nWelcome, %s", argv[1]);
return 0;
}
This should get you started. All you need to do now is write the code to read the string from the standard input and output it to the console.
I have a method execfile which takes the path of an executable file and then executes it, I'm now trying to add the option for the user to enter arguments to the command being executed. I currently have it implemented like so:
int execfile(char *file) {
printf("Enter any arguments to %s: ", file);
char *arg = (char *) calloc(ARG_MAX, sizeof(char));
scanf("%s", arg);
execl(file, file, arg, NULL);
return -1;
}
This does function crudely in that I can execute /usr/bin/ps and enter el or -el at the argument prompt and the function will execute with both arguments as intended.
Ideally though it would be more elegant to be able to enter arguments as you traditionally would when executing a C program directly, so say enter -e -l at the prompt and have it correctly interpreted by the program (currently this wont work), or just immediately press enter to skip the prompt (currently have to enter at least some character).
I thought the best way to do this would be to declare an array char *argv[], set arg[0] = file then scan the rest of the input and place each separate argument in an array cell, then calling execv(file, argv).
I'm very new to C however and am unsure of how this can be implemented in the most efficient way, for example I was considering reading in the whole string first then using a loop to iterate through it character by character to recognise arguments to add to argv, but it seems a bit longwinded? Is there no way to read these arguments into the array directly from stdin?
Additionally I'm unsure what to set ARG_MAX to as I don't know what the limit on number of arguments is within C, and I don't know how to get it to recognise that the enter key has been pressed so to skip immediately.
Is there no way to read these arguments into the array directly from stdin?
In one go, without knowing how many whitespace delimited argument will be passed, and without additional parsing?
No.
I'm trying to use "echo FileName.txt | a.c" in terminal and read the data from the file into a array i got in a header file, but the code I have so far is just giving me a infinite loop. I tried storing the info in a local array also but still the same result.
main(int argc, char *argv[]) {
extern char test[];
FILE *fp;
int i = 0;
int c; // was char c; originally
if (argc == 1) {
fp = stdin;
} else {
fp = fopen (argv[1], "r");
}
while ((c = getc(fp)) != EOF) {
test[i] = c;
printf("%c", test[i]);
i++;
}
}
(1) Change variable c to an int so it recognizes EOF.
(2) Don't increment i before your printf or you will be printing junk.
Not sure what you are trying to accomplish with the echo thing.
NOTE: I'm assuming that your program is intended to do what the code in your question actually does, namely read input from a file named by a command-line argument, or from stdin if no command-line argument is given. That's a very common way for programs to operate, particularly on Unix-like systems. Your question and the way you invoke the program suggest that you're doing something quite different, namely reading a file name from standard input. That's an unusual thing to do. If that's really your intent, please update your question to clarify just what you're trying to do.
Given this assumption, the problem isn't in your program, it's in how you're invoking it. This:
echo FileName.txt | a.c
will feed the string FileName.txt as input to your program; the program has no idea (and should have no idea) that it's a file name.
The way to pass a file name to your program is:
a.c FileName.txt
Or, if you want to read the contents of the file from stdin:
a.c < FileName.txt
(In the latter case, the shell will take care of opening the file for you.)
You could read a file name from stdin, but it's rarely the right thing to do.
A few other points (some already pointed out in comments):
An executable file probably shouldn't have a name ending in .c; the .c suffix indicates a C source file.
You should declare main with an explicit return type; as of C99, the "implicit int" rule was removed, and it was never a particularly good idea anyway:
main(int argc, char *argv[]) { /* ... */ }
You're reading the entire contents of the input file into your test array. This is rarely necessary; in particular, if you're just copying an input file to stdout, you don't need to store more than one character at a time. If you do need to store the contents of a file in an array, you'll need to worry about not overflowing the array. You might want to abort the program with an error message if i exceeds the size of the array.
See also the rest of the advice in Jonathan Leffler's comment; it's all good advice (except that I think he misunderstood the purpose of your test array, which you're using to store the contents of the file, not its name).
This question already has answers here:
Pass arguments into C program from command line
(6 answers)
Closed 6 years ago.
I don't know what to do! I have a great understanding of C basics. Structures, file IO, strings, etc. Everything but CLA. For some reason I cant grasp the concept. Any suggestions, help, or advice. PS I am a linux user
The signature of main is:
int main(int argc, char **argv);
argc refers to the number of command line arguments passed in, which includes the actual name of the program, as invoked by the user. argv contains the actual arguments, starting with index 1. Index 0 is the program name.
So, if you ran your program like this:
./program hello world
Then:
argc would be 3.
argv[0] would be "./program".
argv[1] would be "hello".
argv[2] would be "world".
Imagine it this way
*main() is also a function which is called by something else (like another FunctioN)
*the arguments to it is decided by the FunctioN
*the second argument is an array of strings
*the first argument is a number representing the number of strings
*do something with the strings
Maybe a example program woluld help.
int main(int argc,char *argv[])
{
printf("you entered in reverse order:\n");
while(argc--)
{
printf("%s\n",argv[argc]);
}
return 0;
}
it just prints everything you enter as args in reverse order but YOU should make new programs that do something more useful.
compile it (as say hello) run it from the terminal with the arguments like
./hello am i here
then try to modify it so that it tries to check if two strings are reverses of each other or not then you will need to check if argc parameter is exactly three if anything else print an error
if(argc!=3)/*3 because even the executables name string is on argc*/
{
printf("unexpected number of arguments\n");
return -1;
}
then check if argv[2] is the reverse of argv[1]
and print the result
./hello asdf fdsa
should output
they are exact reverses of each other
the best example is a file copy program try it it's like cp
cp file1 file2
cp is the first argument (argv[0] not argv[1]) and mostly you should ignore the first argument unless you need to reference or something
if you made the cp program you understood the main args really...
For parsing command line arguments on posix systems, the standard is to use the getopt() family of library routines to handle command line arguments.
A good reference is the GNU getopt manual
Siamore, I keep seeing everyone using the command line to compile programs. I use x11 terminal from ide via code::blocks, a gnu gcc compiler on my linux box. I have never compiled a program from command line. So Siamore, if I want the programs name to be cp, do I initialize argv[0]="cp"; Cp being a string literal. And anything going to stdout goes on the command line??? The example you gave me Siamore I understood! Even though the string you entered was a few words long, it was still only one arg. Because it was encased in double quotations. So arg[0], the prog name, is actually your string literal with a new line character?? So I understand why you use if(argc!=3) print error. Because the prog name = argv[0] and there are 2 more args after that, and anymore an error has occured. What other reason would I use that? I really think that my lack of understanding about how to compile from the command line or terminal is my reason for lack understanding in this area!! Siamore, you have helped me understand cla's much better! Still don't fully understand but I am not oblivious to the concept. I'm gonna learn to compile from the terminal then re-read what you wrote. I bet, then I will fully understand! With a little more help from you lol
<>
Code that I have not written myself, but from my book.
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("The following arguments were passed to main(): ");
for(i=1; i<argc; i++) printf("%s ", argv[i]);
printf("\n");
return 0;
}
This is the output:
anthony#anthony:~\Documents/C_Programming/CLA$ ./CLA hey man
The follow arguments were passed to main(): hey man
anthony#anthony:~\Documents/C_Programming/CLA$ ./CLA hi how are you doing?
The follow arguments were passed to main(): hi how are you doing?
So argv is a table of string literals, and argc is the number of them. Now argv[0] is
the name of the program. So if I type ./CLA to run the program ./CLA is argv[0]. The above
program sets the command line to take an infinite amount of arguments. I can set them to
only take 3 or 4 if I wanted. Like one or your examples showed, Siamore... if(argc!=3) printf("Some error goes here");
Thank you Siamore, couldn't have done it without you! thanks to the rest of the post for their time and effort also!
PS in case there is a problem like this in the future...you never know lol the problem was because I was using the IDE
AKA Code::Blocks. If I were to run that program above it would print the path/directory of the program. Example: ~/Documents/C/CLA.c it has to be ran from the terminal and compiled using the command line. gcc -o CLA main.c and you must be in the directory of the file.
Main is just like any other function and argc and argv are just like any other function arguments, the difference is that main is called from C Runtime and it passes the argument to main, But C Runtime is defined in c library and you cannot modify it, So if we do execute program on shell or through some IDE, we need a mechanism to pass the argument to main function so that your main function can behave differently on the runtime depending on your parameters. The parameters are argc , which gives the number of arguments and argv which is pointer to array of pointers, which holds the value as strings, this way you can pass any number of arguments without restricting it, it's the other way of implementing var args.
Had made just a small change to #anthony code so we can get nicely formatted output with argument numbers and values. Somehow easier to read on output when you have multiple arguments:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("The following arguments were passed to main():\n");
printf("argnum \t value \n");
for (int i = 0; i<argc; i++) printf("%d \t %s \n", i, argv[i]);
printf("\n");
return 0;
}
And output is similar to:
The following arguments were passed to main():
0 D:\Projects\test\vcpp\bcppcomp1\Debug\bcppcomp.exe
1 -P
2 TestHostAttoshiba
3 _http._tcp
4 local
5 80
6 MyNewArgument
7 200.124.211.235
8 type=NewHost
9 test=yes
10 result=output