Piping a file from the command line in C - c

I need to access a file provided to the program from the command line in the following fashion: ./myProgram < filename
I figured you could do this with command line arguments (argv and argc), but now realize that this is not the case. I was just wondering where this file is inputted to (name or otherwise) so I can access it.
Thanks in advance!

If you're in a unix shell (zsh, bash, etc.) and do something like ./myProgram <filename, the program dosn't receive <filename in argv array. Instead, the shell parses the part with < and redirects the program's input so that it come from the file filename.
More on i/o redirection here
So, you write exactly as if you were reading from stdin (because you are reading from stdin):
#include <stdio.h>
int main()
{
char str[200];
int i;
scanf("%s", str);
scanf("%d", &i);
printf("%s %d\n", str, i);
}

Related

Reading text file from terminal line?

So I understand that to read and print out a line of text you can just use printf, scanf and type it out. However what if I want to print out a text file without typing them out in terminal? And I don't mean using fopen(filename, "r") where you can only open a specific file. I think this is called redirection but I'm having trouble understanding it. Something along the line as the below input example:
./myprogram < input.txt
Here is a redirection cheat sheet. The line that interest us is:
cmd < file: Redirect the contents of the file to the standard input (stdin) of cmd.
Here a simple example that will print the content of your input.txt file. Compared to manual input, the program will never wait and will loop until the end of the file is reached (Note: there are cases where there is no end, you might want to add alternative break condition).
#include <stdio.h>
int main(void)
{
char buffer[100];
while (fgets(buffer, 100, stdin))
printf("%s", buffer);
return (0);
}
./myprogram < input.txt will print your input.txt
./myprogram will wait for your manual input and print what you just typed.
This is not exactly what you asked but you can put the filename as argument and get it in argv[1] and then use fopen

Why isn't redirected input considered a command line argument?

I'm trying to read command line arguments that have been redirected from a file. The command I'm using is ./a.out < test.txt
And the contents of test.txt is: Hello world.
But the output of my program below isn't printing Hello
world. Instead it is only showing ./a.out. Why is this?
int main(int argc, char* argv[], char* envp[]) {
for (int i = 1; i < argc; i++) {
printf("%s\n", argv[i]);
}
}
The shell intercepts the redirection commands before preparing the command line for the program:
myProg <infile -t >outfile
will pass to the program
myProg -t
with stdin and stdout already rerouted before the pogram starts. So the program never sees the rediretion.
There a lot of cases, besides simple derirection:
dir > myfile.txt
Especially you can pipe output from one program to another:
dir | more
It will send output if dir command to more command. Since program launch handled by OS shell, it handles a redirection too.
Because the language is defined that way. Suppose what you say is true —
All the user input will have to come from command line arguments, but text redirected from a file can satisfy input required in different functions. This can be achieved if the input appears as command line arguments.
Consider this program:
#include <stdio.h>
int is_dict(char *word)
{
/* code to look up a dictionary */
int result = 1;
return result;
}
int main(int argc, char *argv[])
{
if(argc == 2 && is_dict(argv[1]))
printf("%s found", argv[1]);
return 0;
}
If the program is written that way to accommodate it, then the input would have to come from the command line arguments. How would you take input when it is not redirected? It would require more program overhead to detect the missing inputs.
Moreover, imagine a text file containing a million words: it is unfeasible to expect each word to arrive as an argv[n].
There are other objections too. Suppose the program prints a series of prompts for responses. The user would have to know in advance what the prompts are, to supply the answers before the prompts appear.
Lastly, if the program is run from a GUI, then all the program's input will have to be edited into its properties before it is run.

Ipconfig /all using C programming leads to incomplete command line error

A programming beginner here so I am working on a simple program that uses the user's input to name a text file and then the program stores the ipconfig /all information in that text file. I receive an error "unrecognized or incomplete command line." I understand it's quite easy to write the ipconfig /all to a text file using the command prompt but I was hoping to get it working using C.
Thank you!
#include<stdlib.h>
#define MAX_LEN 20
int main()
{
char myfile[MAX_LEN];
printf ("Enter text file name: ");
scanf ("%s", myfile);
system("C:\\Windows\\System32\\ipconfig /all 2>&1 \\Location\myfile.txt");
return 0;
}
a lot of errors here
not using the string you just inputted
wrong escaping of backslashes
forgetting a redirection in the command line (just before the filename). Ex: system("C:\\Windows\\System32\\ipconfig /all 2>&1 > myfile.txt")
but:
you shouldn't use system for this, popen can get a command output, no need for ugly redirections
no need to silence standard error, all the interesting output is in standard output
no need to specify the path for the command it's a system command already in the path
my proposal using popen (which is missing some error checking and whatnot, but basically works) which returns you a pipe handle. Just read it char by char until the end and write the result in an output file:
#include<stdio.h>
#define MAX_LEN 20
int main()
{
char myfile[MAX_LEN];
printf ("Enter text file name: ");
fflush(stdout);
scanf ("%19s", myfile);
FILE *f = popen("ipconfig /all","r");
FILE *fw = fopen(myfile,"w");
if (fw)
{
while(1)
{
int c = fgetc(f);
if (c == EOF) break;
fputc(c,fw);
}
fclose(fw);
pclose(f);
}
return 0;
}

Command Line argument in C not printing correctly

im trying to test how my program is receiving a users command line input:
my command line input to test is:
"./concordance 15 < input.txt"
the rest of the program works but to test the arguments. so in my main function i have this:
int main(int argc, char *argv[])
{
int i;
for (i = 0; i < argc; i++)
{
printf("%s\n", argv[i]); //runs through command line for arg
}
printf("%d\n", argc); //prints total arguments
return 0;
}
The problem is when I enter my command line, the program prints:
./concordance
15
2
for my program to work I need to open the input.txt file so my question is, why is the program only printing "./concordance", and "15" aswell as only seeing 2 arguments if I have "<" and "input.txt" in the command line?
Thanks
< is not interpreted as a command line argument but is instead interpreted by the shell to redirect standard input to be the specified file instead of the parent standard input, typically the shell.
There is a difference between the command line and "stdin" - "15" is a command line argument. The shell sees the '<' and "redirects" the file to your program on it's stdin stream.
If you don't want to use stdin to process the file, just pass it's name and open yourself: ./concordance 15 input.txt (argv[2] will be input.txt)

How do I read file into a command line?

Basically what I want to do is have a program with int main(argc, *argv[]) and instead of writing chars into command line, I want to have my program read those words from a file. How could I accomplish this? Is there a special command in Linux for that?
You can use standard redirect operations in a *nix shell to pass files as input:
./myprogram < inputfile.txt
This statement executes your program (myprogram) and pumps the data inside of inputfile.txt to your program
You can also redirect the output of program to a file in a similar fashion:
./myprogram > outputfile.txt
Instead of doing
for(int i = 1; i < argc; i++)
{
insert(&trie, argv[i]);
}
you could doing something like
FILE *input;
char *line;
....
while (fscanf(input, "%ms", &line) != EOF) {
insert(&trie, line);
/* If you make a copy of line in `insert()`, you should
* free `line` at here; if you do not, free it later. */
free(line);
}
Use redirection
yourprogram < youtextfile
will offer the content of yourtextfile as standard input (stdin) to yourprogram. Likewise
yourprogram > yourothertextfile
will send everything the program writes to standard output (stdout) to yourothertextfile
You'll notice when reading man pages that most system calls have a version that works directly with stdin or stdout
For example consider the printf family:
printf ("hello world\n");
is a shorter version of
fprintf (stdout,"hello world\n");
and the same goes for scanf and stdin.
This is only the most basic usage of redirection, which in my opinion is one of the key aspects of "the unix way of doing things". As such, you'll find lots of articles and tutorials that show examples that are a lot more advanced than what I wrote here. Have a look at this Linux Documentation Project page on redirection to get started.
EDIT: getting fed input via redirection ior interactively "looks" the same to the program, so it will react the same to redirected input as it does to console input. This means that if your program expects data line-wise (eg because it uses gets() to read lines), the input text file should be organized in lines.
By default, every program you execute on POSIX-compliant systems has three file descriptors open (see <unistd.h> for the macros' definition): the standard input (STDOUT_FILENO), the standard output (STDOUT_FILENO), and the error output (STDERR_FILENO), which is tied to the console.
Since you said you want read lines, I believe the ssize_t getline(char **lineptr, size_t *n, FILE *stream) function can do the job. It takes a stream (FILE pointer) as a third argument, so you must either use fopen(3) to open a file, or a combination of open(2) and fdopen(3).
Getting inspiration from man 3 getline, here is a program demonstrating what you want:
#define _GNU_SOURCE
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
size_t len;
char *line;
ssize_t bytes_read;
len = 0;
line = NULL;
if (argc > 1)
{
fp = fopen(argv[1], "r");
if (fp == NULL)
{
perror(*argv);
exit(EXIT_FAILURE);
}
}
else
fp = stdin;
while ((bytes_read = getline(&line, &len, fp)) != -1)
printf("[%2zi] %s", bytes_read, line);
free(line);
exit(EXIT_SUCCESS);
}
Without arguments, this program reads lines from the standard input: you can either feed it lines like echo "This is a line of 31 characters" | ./a.out or execute it directly and write your input from there (finish with ^D).
With a file as an argument, it will output every line from the file, and then exit.
You can have your executable read its arguments on the command line and use xargs, the special Linux command for passing the contents of a file to a command as arguments.
An alternative to xargs is parallel.

Resources