C - main() command line parameters - c

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]);

Related

how to write a command line to a file in c

I'm having issues with writing this command line to a file and it's suppose to output to the screen. To me, my code looks like it should work but I'm at a complete loss (this is my first time programming in C)
Print one line describing your program
Open the first parameter as a file for writing. If no parameter is provided, write to the stdout handle
Using a loop, save the contents of the array of string pointers passed as a parameter to the main function into the file open for writing. This is usually the variable named argv.
int main(int argc, char *argv[])
{
FILE *fp;
int i;
printf("Output supplying 'multiple arguments' to this program");
fp = fopen(argv[1], "w"); //Write to file
if(fp==NULL)
{
fp = stdout;
}
for(i=0;i<argc;i++)
{
fprintf(fp, argv[i]);
}
printf("The number of arguments printed %d", argc);
return 0;
Any help provided would be greatly appreciated!
Don't ever use dynamic format strings in C. This opens you up to an extensive set of bugs, several of them security-sensitive. Instead, pass a format string that indicates your intent, like so:
for(i=0;i<argc;i++)
{
fprintf(fp, "%s\n", argv[i]);
}

Finding segmentation fault in C

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

Reading file when compiling

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).

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;
}

why do I get errno EINVAL (innvalid parameters) but only when the file is empty

I use _fsopen(path, "r+", _SH_DENYRW) for opening a file in C any parameter for protection (_SH_...) cause the same issue.
When opening an empty file, errno is set to 22 (EINVAL), not so when the file isn't empty - then all is OK. What can I do?
The documentation implies that EINVAL would the result if one of the parameters were invalid. Since "r+" has to be a valid pointer, and assuming it compiled at all _SH_DENYRW has to be a valid flag, the only remaining question is whether your variable path is not NULL, points to memory that exists and can be read, and contains a valid path name.
I just tried the following:
#include <stdio.h>
#include <share.h>
int main(int argc, char **argv)
{
FILE *f;
if (argc != 2) {
fprintf(stderr, "Usage: %s file\n", argv[0]);
exit(1);
}
f = _fsopen(argv[1], "r+", _SH_DENYRW);
if (f) {
printf("Open ok.\n");
fclose(f);
} else {
perror(argv[1]);
}
return 0;
}
On files that exist and can be written, regardless of their size, it prints "Open ok.", meaning that _fsopen() succeeded. A couple of other cases:
A read-only file:
C:>fsopen ro.txt
ro.txt: Permission denied
No file:
C:>fsopen nosuchfile
nosuchfile: No such file or directory
A device file:
C:>fsopen NUL:
Open ok.
A zero-length file:
C:>fsopen zero.txt
Open ok.

Resources