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).
Related
I'm new to C and I'm trying to open a file and print its content line by line to console.
The source code is attached along with a couple screen shots to show my situation. (The redded-out part contain my computer's directories and personal info). As you can see from the screenshot, the program prints "before" but not "after". Of course, neither does it print out anything from coc.txt.
I can't figure out why this is the case. Everything seems correct and I don't see any errors.
#include <stdio.h>
#include <stdlib.h> // For exit()
const int MAX_LINE_LENGTH = 300;
int main() {
FILE *inputFile;
inputFile = fopen("coc.txt", "r");
char lineRead[MAX_LINE_LENGTH];
printf("before\n");
while(!feof(inputFile)) {
fgets(lineRead, MAX_LINE_LENGTH, inputFile);
puts(lineRead);
}
fclose(inputFile);
printf("after\n");
}
console
coc.txt
Here's a suggested alternative (not tested yet):
#include <stdio.h>
#define MAX_LINE_LENGTH 300
#define NULL 0
int main(int argc, char *argv[]) {
FILE *inputFile;
char fname[MAX_LINE_LENGTH], lineRead[MAX_LINE_LENGTH];
/* Get filename from cmd-line */
if (argc != 2) {
printf ("USAGE: progname <fname>\n");
return 1;
}
/* Try to open file */
if ((inputFile = fopen("coc.txt", "r")) == NULL) {
perror("Could not open file");
return 2;
}
/* Now read the file, and echo back a line at a time */
printf("before...\n");
while(fgets(lineRead, MAX_LINE_LENGTH, inputFile) != NULL) {
printf ("%s", lineRead);
}
printf("\n...after\n");
/* Cleanup and exit */
fclose(inputFile);
return 0;
}
Changes:
Be sure to have a "return" from main ().
In general, a graceful "return" from main() is preferred over a system call to "exit()".
Read the input, then to check for EOF (fgets() == NULL).
Make sure you've opened the file before reading.
Rather than hard-coding the filename, we're reading it from the command line.
Rather than puts() (which always appends a newline, regardless of whether the string already has a newline), we're using printf().
Make sure that the coc.txt file and the read.c files are in the same folder. I executed your original code and it works fine with VS 2017 on windows 10.
I am trying to check if a file exists by opening it with fopen() and then checking if the function returns NULL. But when I run the code, it says a read access violation error accured, but I don't get why, since I checked and the file I am trying to read is txt and has text already written in it. Can someone explain why and how I can fix it?
int main(int argc, char** argv)
{
int quit = FALSE;
if (fopen(*(argv+2), 'r') == NULL)
{
printf("Invalid input! File does not exit.");
quit = TRUE;
}
}
First, from the fopen manual, we can see that the function signature is:
FILE *fopen(const char *pathname, const char *mode);
What this means is that it will return a pointer of type FILE, and expects two arguments, both pointers to char. The second argument you pass to fopen in your code is a char, not a char*, so we need to fix that. Also, store the returned fopen pointer, as you should use it to close the file after you're done with it.
So, your code would be something like:
FILE *fp;
if ((fp = fopen(argv[2], "r")) == NULL) {
printf("File does not exist!\n");
exit(0);
} else {
/* file exists... do stuff */
fclose(fp);
}
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;
}
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.