How would you ask for the user to input files as arguments to be used (as many as they would like)? Also How would you print to a file?
scanf("%s", user_filename);
FILE *fp;
fp = fopen (user_filename, "r");
I have tried doing various things to it but I can only get it to take one file.
The easiest way to pass some file names to your C program is to pass them as arguments to your C program.
Arguments are passed to a C program using the parameters to main:
int main( int argc, char *argv[] )
{
...
}
The value argc indicates how many parameters there are, and argv[] is an array of string pointers containing the arguments. Note that the first argument at index 0 (the string pointed to by argv[0]) is the command name itself. The rest of the arguments passed to the command are in argv[1], argv[2], and so on.
If you compile your program and call it like this:
my_prog foo.txt bar.txt bah.txt
Then the value of argc will be 4 (remember it includes the command) and the argv values will be:
argv[0] points to "my_prog"
argv[1] points to "foo.txt"
argv[2] points to "bar.txt"
argv[3] points to "bah.txt"
In your program then, you only need to check argc for how many parameters there are. If argc > 1, then you have at least one parameter starting at argv[1]:
int main( int argc, char *argv[] )
{
int i;
FILE *fp;
// If there are no command line parameters, complain and exit
//
if ( argc < 2 )
{
fprintf( stderr, "Usage: %s some_file_names\n", argv[0] );
return 1; // This exits the program, but you might choose to continue processing
// the other files.
}
for ( i = 1; i < argc; i++ )
{
if ( (fp = fopen(argv[i], "r")) == NULL )
{
fprintf( stderr, "%s: Gah! I could not open file named %s!\n", argv[0], argv[i] );
return 2;
}
// Do some stuff with file named argv[i], file pointer fp
...
fclose( fp );
}
return 0;
}
This is just one of several different ways to do it (functionally and stylistically), depending upon how you need to process the files.
Related
im currently doing a project which works with input files.
The code is doing everything that i want, and its fully correct, the problem is the way im reading the file.
FILE *fp;
fp = fopen (argv[1], "r");
in the terminal im using ./filec input.in, and everything gets printed correctly in the terminal, but i have to open the file in this way:
./filec < input.in > < output.myout > and im not sure what does that entail.
Thank you, and sorry for the poor english
Your argv[1] would have the input file, and yourargv[2] would have the output file.
A basic beginning layout for you to work on would be:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
if (argc != 3)
{
exit(EXIT_FAILURE); //If there are not three arg, terminate the program.
}
FILE *fp_read, *fp_write;
fp_read = fopen(argv[1],"r");
fp_write = fopen(argv[2],"w");
//Do whatever you want with it.
fclose(fp_read);
fclose(fp_write);
return 0;
}
I assume you have a typo and you actually mean:
./filec < input.in > output.myout
Basically, this means you are letting the shell do all the work for you, and your code can simply read from stdin and write to stdout. You might try:
fp = argc > 1 ? fopen(argv[1], "r") : stdin;
It could be you misunderstood the --help option, the first notation you describe is, for commandline arguments, the correct one. "" is just a notation that is used, meaning that you can change the name of the parts between <>.
Anyway, if you really need to use that notation to call your program, you could make a new array containing the argv[1] without <>.
pseudo code:
char newFilename[20];
//skip first and last character (if needed, changes values to skip first two and last two chars
for(i = 1; i < argv[1].length - 2; i++){
newFilename[i - 1] = argv[1][i];
}
fp = fopen (newFilename, "r");
Note that the < and > characters are interpreted as file redirection operations, so you should do (in this case) ./youprogram "< file.in >" "< file.out >"
First, read about fopen(3) and stdio(3)
You want to read from stdin
When calling fopen you always should check for failure, e.g. (after having tested that argc>1, assuming you defined int main(int argc, char**argv) as is conventional!)
FILE *fp = fopen (argv[1], "r");
if (!fp) {perror(argv[1]); exit(EXIT_FAILURE); };
so you probably want:
FILE *fp = NULL; // I prefer always initializing variables
if (argc>1) {
fp = fopen (argv[1], "r");
if (!fp) {perror(argv[1]); exit(EXIT_FAILURE); };
}
else fp = stdin;
If you invoke your program as ./myprog < someinput.txt > someoutput.txt then everything you printf, putchar or send to stdout goes into someoutput.txt, and stdin is the someinput.txt. Generally the redirection is done externally (by the shell on POSIX systems)
I've commented all the code I thought was giving me an error, but I'm still getting it. this is my code:
int main(int argc, char **argv) {
// argc is the number of command line arguments, in our case there are two
// argv is an array of pointers, a[0] is the program name, a[1] will be sourcewav
// and a[2] should be destwav
FILE * source_file;
FILE * destination_file = fopen(argv[2], "w") ; // create destwav file
if (argc != 3) {
printf("Usage: requires two parameters: sourcewav and destwav");
exit(1);
}
//source_file = fopen(argv[1], "r+");
if (!source_file) { // pointer is null, file can't be opened
printf("Usage: %s sourcewav file cannot be opened\n", argv[0]);
exit(1);
}
printf("1");
remvocals(source_file, destination_file); // remove vocals
int closed_properly = fclose(source_file); // has source_file successfully closed?
if (closed_properly != 0) {
printf("Usage: %s sourcewav was not closed properly\n", argv[0]);
exit(1);
}
fclose(destination_file);
return 0;
}
you check sourcefile without initializing it. In addition, what remvocals does?
Move
if (argc != 3) {
printf("Usage: requires two parameters: sourcewav and destwav");
exit(1);
}
Before the declaration of your FILE pointers. Also, uncomment the line that initializes source_file. I think that you need argv[1] instead of argv[0] as the second argument of the printf placed in the body of the second and third ifs.
You haven't given enough information.
In your code, obvious concerns are;
1) destination_file is never checked to see if the fopen() succeeded. If destination_file is NULL, any operations on it (fprintf(), fclose()) will give undefined behaviour. The fopen() needs to be AFTER the check of argc, not before.
2) With the "source_file = fopen(argv[1], "r+")" statement commented, source_file is an uninitialised variable. Accessing its value - let alone passing it to I/O functions as a file argument - will give undefined behaviour.
3) You have a function called remvocals() which (presumably) is copying data from source_file to destination_file, but you have provided no information whatsoever about it. Even if the preceding two concerns are addressed, there are many things that function could be doing that introduce undefined behaviour.
Given all the above, it is quite possible your code is not even representative of your actual problem. You would be better off providing a small and complete sample that - when built - actually demonstrates your problem. Otherwise, people trying to help you are resorting to guesswork.
//source_file = fopen(argv[1], "r+");
if (!source_file) { // pointer is null, file can't be opened
printf("Usage: %s sourcewav file cannot be opened\n", argv[0]);
exit(1);
}
It looks to me, you forgot to uncomment this line:
//source_file = fopen(argv[1], "r+");
You also should move:
if (argc != 3) {
printf("Usage: requires two parameters: sourcewav and destwav");
exit(1);
}
Before the line where you fopen in this line:
FILE * destination_file = fopen(argv[2], "w") ; // create destwav file
I'm working on a program and it's something I can't understand. I have a main function with arguments:
int main(int argc, const char *argv[]){
FILE *file;
file=fopen(argv[1], "r");
if( file == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
How do I read the argv[1] file. When I compile it error shows up as Invalid argument. How do I get the file to open so I can print the things it's hiding? I'm using Code Blocks.
The argv[1] refers to the first argument passed by the user on the command line. argv[0] refers to the file itself. So in your case, the program will open the file passed as the first argument.
./myprogram myfilename.txt
Moreover, you have a few issues with the program itself.
#include <stdio.h> /* Library needed for input/output*/
#include <stdlib.h> /* needed for the exit calls*/
int main(int argc, const char *argv[]){
FILE *file;
file=fopen(argv[1], "r");
if( file == NULL )
{
perror("Error while opening the file.\n");
exit(1);
}
return 0;
}
This obviously doesnt do much right now but it will get argv1 open.
Also, I changed exit(EXIT_FAILURE) to exit(1). They are mostly synonymous but exit(1) doesn't require a compiler flag (-std=c99). EXIT_FAILURE is considered more portable - EXIT_FAILURE vs exit(1)? - but again for simplicity, I changed it to exit(1).
This is a really basic question but I can't find a definitive answer anywhere.
I understand the parameters of main, as far as what they refer to:
int main(int argc, char *argv[])
where argc refers to the number of command line arguments and argv refers to the array that holds each of the strings. I created an exe file of the source code from the .c file, but have no experience with command prompts and don't understand the syntax of the command line arguments.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *infile, *outfile;
int iochar;
if(argc != 3){
printf("Usage: filename infile outfile\n");
exit(1);
}
if((infile = fopen(argv[1], "r")) == NULL){
printf("Can't open input file.\n");
exit(1);
}
if((outfile = fopen(argv[2], "w")) == NULL){
printf("Can't open output file.\n");
exit(1);
}
while((iochar = getc(infile))!=EOF){
putc(iochar, outfile);
}
fclose(infile);
fclose(outfile);
printf("You've reached the end of the program.\n");
return;
}
The preceding code should take 3 arguments and copy the 2nd argument's contents into the 3rd argument's location. What do I have to do for this to happen?
You can set the command line arguments in the Debug properties of your VS project.
don't understand the syntax of the command line arguments.
The details of the syntax of the command line arguments depends on what program is interpreting them ... VS, a Windows shortcut, Windows cmd, bash, etc. ... but generally it's just a list of items separated by spaces. If the items themselves contain spaces, quotes, or other special characters, then you need to pay attention to the rules of the interpreter you're using.
The semantics of the command line arguments is defined by your program ... in this case, the first argument is the name of the input file and the second argument is the name of the output file.
printf("Usage: filename infile outfile\n");
This is not a good usage message ... the "filename" should be the name of your program, which is generally the value of argv[0]. Thus:
printf("Usage: %s infile outfile\n", argv[0]);
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;
}