I'm making a program that read CSV files based on the arguments of the C program called read-log
example
$ ./read-log file1.csv
$ ./read-log file1.csv file2.csv nofile.csv
But I also need my program to read files when using the unix command cat but when I input:
$ cat file1.csv |./read-log
The program doesn't get any argument.
Just use the FILE *stdin that is open by default:
FILE *fp;
if (argc > 1) {
if (strcmp(argv[1], "-") == 0) // Many utilities accept "-" for the
fp = stdin; // filename to indicate stdin
else
fp = fopen(argv[1], "r");
}
else {
fp = stdin;
}
When you're done using the file, make sure you only close it if you actually opened it: (Closing stdin can lead to some interesting bugs down the road!)
if (fp != stdin)
fclose(fp);
Related
I am writing a program that reads from a file passed as an arguement, or reads from stdin if no arguements are given.
The code runs fine with a file passed, but I get a seg fault when no file is passed.
I basically call fopen on argv[1] if a file was given, but if no file was given I call:
f = fopen("stdin", "r");
Is this the correct syntax for opening stdin as a file?
When you start a program, the main() function is not the first thing that
get's called, quite a few things happen before the main() function is
called. One of those things is to open stdin, stdout and stderr. In
general you don't need to worry about the details how the OS does that, you
just can relay that when main() is executed, these streams are open and you
can use them.
So in your case, you can do this:
#include <stdio.h>
int main(int args, char **argv) {
FILE *fp;
if(args == 1) {
fp = stdin;
} else {
fp = fopen(argv[1], "r");
if(fp == NULL) {
fprintf(stderr, "Unable to open %s for writing\n", argv[1]);
return 1;
}
}
// do your read operations on fp
if(fp != stdin) {
fclose(fp);
}
return 0;
}
So when you call the program without arguments, stdin is used, otherwise a
file is used.
The reason why your code crashes is because
f = fopen("stdin", "r");
tries to open a file literally called stdin, which you most probably don't
have. fopen will return NULL and you probably don't check for that. If you
try to use a function that expects a FILE* pointer but pass NULL, then
you'll most likely will get a segfault.
USE f = stdin;
NOT f = fopen("stdin", "r");
I want to open file named ex1, ex2, ex3 ...exn etc.
Now when i put the value of n like, n=1, ex1 will be opened
for, n=2, ex2 file will be opened and then I will read or write my c program output array from or into it.
can the name of the file be given as a string?
As I am new with programing please help me to solve this problem.
Normally when you open a file you use the function fopen
fp = fopen ("file.txt", "w+");
if (fp == NULL)
{
exit(1); // Or you can raise some error code and return if this code is in a function.
}
// Process the file
Now in your case, you need to manipulate the filename. So you can take a C string for this.
char filename[10];
// N is set from code above
sprintf(filename,"ex%d",N);
fp = fopen (filename, "w+");
// Further behaviour is same
I'm using "system" API calls to run shell commands in my C program, now
there is case where I want to redirect the output generated by an executableto a buffer instead of a file (named recv.mail)
An example of how I write the output to the file:
cmd[] = "mda "/bin/sh -c 'cat > recv.mail'";
system (cmd);
Similarly I want to replace input taken from the file (send.mail) with input taken from a buffer.
An example of how I take input from a file:
cmd[] = "msmtp < cat send.mail";
system (cmd);
NOTE: The send.mail and recv.mail files have formatted data.
Are pipes a better replacement?
Can anyone suggest another alternative?
popen/pclose may do what you want:
FILE *f = popen("program to execute", "r");
if (NULL != f)
{
char buffer[128];
while (fgets(buffer, sizeof buffer, f)
{
printf("Read from program: '%s'\n", buffer);
}
pclose (f);
}
popen/pclose again:
FILE *f = popen("program to execute", "w");
...
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)
In C, stdin is a valid file pointer, thus we could use stdin (and the 2 others) with the "file" version of the input functions if we want or need to.
Why might us need to (Rather than just pipe in from shell)? Could anyone come up with some examples please?
Here's an example:
FILE * input = argc == 2 ? fopen(argv[1], "r") : stdin;
fgets(buf, sizeof buf, input);
Now you can use your tool as magic data.txt and as magic < data.txt.
If you write a function that works on any FILE *, and at a higher level you decide that you want the output to go to stdout. Or read from any FILE * and instead you decide to read from stdin.
If you at, for example, the program wc which counts characters in a file, you'll see that it can read from stdin or from a file name given as a command line argument. This decision could be made in the main by checking to see if the user provided a file name with $ wc file.txt or called with just wc, or piped input from something else $ ls -l | wc
$ wc # reads from stdin
$ wc file.txt # counts characters in file.txt
$ ls -l | wc # reads from stdin also.
and you can imagine a simple main which says:
int count_chars(FILE *in);
int main(int argc, char *argv) {
if (argc == 2) { // if there is a command line argument
FILE *input = fopen(argv[1], "r"); // open that file
count_chars(input); // count from that file
} else {
count_chars(stdin); // if not, count from stdin
}
return 0;
}
Additionally to print errors one would use fprintf(stderr, "an error occured\n");