So I'm trying to get the C program to read a filename from the command line in the following format:
cat (filename path) | (program name)
i can get it to read the name of the input file when its entered as a command line argument, but it won't read from the concatenated argument
here's the code, right now its reading the name of the file as if written after the program name on the command line.
#include <stdio.h>
#include <string.h>
//initialize file pointer
FILE *file;
//initialize global variables
#define DEFAULT_LEN 70
//main
int main(int argv, char *argc[]){
//open File for reading
file = fopen (argc[1],"r");
//test for failure of file open, if failed, print message, quit
if(file == NULL){
printf("I'm sorry Dave, I'm araid I can't do that.\n");
printf("Open the file \"%s\" that is.\n", argc[1]);
return(0);
}
//read the first line of a file into an array
char temp[DEFAULT_LEN]; //where the read data is put
fgets(temp,DEFAULT_LEN,file); //stops at DEFAULT_LEN on \n
//print out temp
printf("%s\n", temp);
//close file, return 0 for main
fclose(file);
return(0);
}
any help would be appreciated
The reason your program can't get the file name is because you're not giving it to it.
If you run your program as:
prog hello.txt
it's given the argument hello.txt in argc/argv.
However, what you're doing is:
cat hello.txt | prog
which means the shell is opening the file and feeding it into the standard input of your program. Actually, to be more accurate, cat is opening the file and the shell is simply connecting the standard output of cat to the standard input of prog.
One way around this is to check the number of arguments (argc is usually the count, argv[] the values, despite the roundabout way you have it in your code) and, if it's zero, argc == 1, read your file from standard input.
Only if an argument is given do you open that file and read it. That's the way a lot of UNIX utilities work:
od -xcb hello.txt # will dump the file.
cat hello.txt | od -xcb # will dump the file, but using standard input.
echo hello | od -xcb # will dump your "hello" string.
Some even change their behaviour depending on how they're invoked, wc being one example - it shows the file name(s) if it knows them:
pax> wc -l qq.c
29 qq.c
pax> cat qq.c | wc -l
29
pax> wc -l *.c
0 a b.c
168 binmath.c
49 qq-save.c
29 qq.c
11 qq2.c
5 qqq.c
18 xx.c
280 total
pax> cat *.c | wc -l
280
Note that last case - because all files are being presented over the single standard input stream, there's no way to tell how many files there are. wc will just tally up the entire contents of that stream.
Try this instead:
#include <stdio.h>
#include <string.h>
#define DEFAULT_LEN 70
int main (int argc, char *argv[]) {
FILE *file;
// Either select standard input or open the given file.
if (argc == 1) {
file = stdin;
} else {
file = fopen (argv[1], "r");
if (file == NULL) {
printf ("I'm sorry Dave, I can't do that\n");
printf (" (open the file '%s', that is).\n", argv[1]);
return 1;
}
}
// Now you're connected to stdin or the file itself, no
// difference in handling them (unless you do weird fseek
// sort of stuff).
char temp[DEFAULT_LEN];
fgets (temp, DEFAULT_LEN, file);
printf ("%s\n", temp);
// Only close file if you opened it yourself.
if (argc != 1)
fclose (file);
return 0;
}
This allows you to use both the file and standard input method as follows:
pax> prog prog.c
#include <stdio.h>
pax> echo hello | prog
hello
Piping content into a process does not put the values into argv; rather, it puts the values onto that process's stdin.
You need to check if argc is greater than 1. If it is, then argv[1] has the filename you've been given (well, the first argument to the program, anyway). If not, you need to read from stdin to get the filename.
To read from the contantenated, you need to read from STDIN
char c = (char)fgetc(stdin)
Related
So i trying to input multiple files in the assigned program.
My input file code is as such:
int read_File(int *hp, int *d, int *s, char t[])
{
FILE *infile;
infile = fopen("input1.txt", "r");
if (!infile)
{
return 0;
}
else
{
fscanf(infile, "%d", hp);
fscanf(infile, "%d", d);
fscanf(infile, "%d", s);
fscanf(infile, "%s", t);
fclose(infile);
return 1;
}
i did
$>gcc assignedProgram.c -o nqt
$>./nqt input1.txt
but if i want to read input2.txt, i have to change from input1.txt to input2.txt in the codes. Is there anyway to bypass that and read input2.txt without changing from input1.txt to input2.txt in the codes
like when i tried ./nqt input1.txt => it's normal
BUT ./nqt input2.txt it's segmentation fault:11
I tried:
to change "input1.txt" in the codes to "nqt" but that was a dumb idea
and BTW: what is ./nqt
Please help me!
You must write main() as one of the equivalent forms below
int main(int argc, char **argv) { /*...*/ }
int main(int argc, char *argv[]) { /*...*/ }
so that argc and argv are set up by your environment to proper values.
For example
$ ./nqt input.txt
^^^^^ ^^^^^^^^^ --> 1
\\\\\-------------> 0
Translates in your program to
argc == 2
argv[0] ==> pointer to "./nqt"
argv[1] ==> pointer to "input.txt"
argv[2] ==> NULL
When it comes to nqt, it is the name of the program you specified with -o flag when compiling: gcc assignedProgram.c -o nqt. In order to run the program, you need to use ./ prefix, thus ./nqt means "run the program called nqt".
If you want to pass the name of the file as an argument, you should tell main function to accept command line arguments: int argc and char* argv[] (you can read about it here). Then the name of the file you will pass by running ./nqt <filename> would be stored in argv[1], which you should pass to read_File function as an argument.
In study course i need to use 2 programs in same time to writing strings in one file.
I typed two similar programs on C:
#include <stdio.h>
int main(int argc, char** argv)
{
FILE *f;
f = fopen("output.txt", "w+");
while (1)
{
fprintf(f, "%s", "kill me pls \n");
}
return 0;
}
and
#include <stdio.h>
int main(int argc, char** argv)
{
FILE *f;
f = fopen("output.txt", "w+");
while (1)
{
fprintf(f, "%s", " NO! \n");
}
return 0;
}
And then i compiled and tried to run this programs in same time, using command
./prog1 & ./prog2 &
But nothing happening. In console i saw:
stolz$ ./prog1 & ./prog2 &
[7] 3920
[8] 3921
How must i type shell command to run this programs in the same time?
How must i type shell command to run this programs in the same time?
The way you proposed in your question was the right way:
$ ./prog1 & ./prog2 &
[7] 3920
[8] 3921
That starts both of the programs running in the background at the same time.
What happens then: Your code opens the output.txt using fopen w+. man fopen tells us:
w+ Open for reading and writing. The file is created if it does not
exist, otherwise it is truncated. The stream is positioned at the
beginning of the file.
Lets change that to a+ and modify your code by adding a sleepand a fflush for it:
#include <stdio.h>
#include <unistd.h> # that also need this
int main(int argc, char** argv)
{
FILE *f;
f = fopen("output.txt", "a+"); # changed w+ to a+
while (1)
{
fprintf(f, "%s", "kill me pls \n");
fflush(f); # this for that:
sleep(1); # that
}
return 0;
}
Make the above changes to prog2.c also, compile them:
$ gcc -o prog1 prog1.c ; gcc -o prog2 prog2.c
and start them and tail the output.txt:
$ ./prog1 & ./prog2 &
[1] 6976
[2] 6977
$ tail -f output.txt
kill me pls
kill me pls
kill me pls
NO!
kill me pls
NO!
kill me pls
NO!
kill me pls
Well, I am learning programming in C, and I got an assignment to get 3 characters from an input text file into 3 variables and then print their ASCII values.
I wrote this code:
#include <stdio.h>
int main()
{
char a,b,c;
printf("Insert 3 characters:\n");
a=getch();
b=getch();
c=getch();
printf("%d, %d, %d",(int)a,(int)b,(int)c);
}
I opened a text file (input.txt) and wrote there: "abc".
I managed to compile the code with the MinGW compiler, and on the CMD window that I opened in the folder of the .exe file, I wrote: "Task.exe <input.txt".
The program ran normally. I mean, it waited for me to input 3 characters.
What have I done wrong in my work?
help me please :)
You are asked to read from an input text file.
Why don't you use fopen to open a file handle, and fgetc to read from it?
You could perhaps use fscanf. Don't forget to use the resulting count.
And of course, you should call fclose. Using perror is useful to handle error cases.
So start your code with something that checks that your program has an argument, then fopen it:
int main(int argc, char**argv) {
if (argc<2) { fprintf(stderr, "missing program argument\n");
exit(EXIT_FAILURE); };
FILE* fil = fopen(argv[1], "r");
if (!fil) { perror(argv[1]); exit(EXIT_FAILURE); };
Then run Task.exe input.txt in your console (no redirection needed!).
You should take the habit of reading the documentation of every function you are using, of testing failure cases, of compiling with all warnings & debug info (gcc -Wall -Wextra -std=c99 -g), and of using the debugger (gdb).
I'm trying to write a program that will read the first character in a text file. If I use ./a.out myfile.txt it works as intended but if I use ./a.out <myfile.txt I get Segmentation fault: 11. The reason why I'm trying to include the <is because this what is in the spec of the assignment. The below code is just a simplified example that i've made that has the same issue:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int func(int argc, char **argv){
FILE *fp;
int test = 0;
fp = fopen(argv[1], "r");
fscanf(fp, "%i", &test);
printf( "current file: %s \n", argv[1]);
}
int main(int argc, char **argv){
func(argc, argv);
}
Is there any way I can get it to accept the argument as <myfile.txt?
No, nor should you try. Files redirected this way will appear at stdin and you should use that instead (hint: check argc).
If you want to use a file if specified, but otherwise stdin, use something like:
if (argc > 1)
fp = fopen(argv[1], "r");
else
fp = stdin;
In your command ./a.out <myfile you redirect stdin to myfile. This means reading from stdin is actually reading from myfile. So, in this case your argc == 1, so argv[1] you use to open is NULL (see main spec on its arguments). fopen crashes when uses NULL name.
You may do your utility in another way: always read stdin. When you need file to input do like this: cat myfile | ./a.out. This is very nice approach and worth considering.
I have two programs (Prog1.c and Prog2.c) written in C and each of them take one command line argument.
Prog1.c takes a file name as argument , reads content from file and outputs it on the STDOUT (standard output) screen. Prog2.c takes data as argument and does some operation. I want to redirect output of Prog1.c to Prog2.c as input.
I have tried following bash script which gives me error
#!/bin/bash
prog2 "`prog1 file.txt`"
I have also tried without quotes and in both cases, it gives me following error.
Prog2:: argument list too long.
To get the output of a command as a parameter for another command you can use backticks:
prog2 "`prog1 file.txt`"
or use $() (I believe this is a more preferred way for bash):
prog2 "$(prog1 file.txt)"
If you want to use the STDOUT of prog1 as STDIN for prog2 use the | (pipe) operator:
prog1 | prog2
Note: When you want to use pipes, you need to modify the code of prog2, as it needs to read from STDIN instead of the command arguments (argv of the main() function). See How to read a line from the console in C? for an example on how to do this.
PIPES!!!!!
On the command line (or in your script) do prog1 file.txt | prog2
You must use backticks in both places before and after prog1
prog2 "`prog1 file.txt`"
When you get "argument list too long", you have reached the system limit for the command line. You must then find another way to send the data to prog2. You can read from stdin instead, and pipe the output of prog1 to prog2
prog1 file.txt | prog2
When you pipe the data from prog1 to prog2, you must change prog2 and read from stdin instead of using argv.
Example reading line by line:
char buf[1024];
while (fgets(buf, 1024, stdin)) {
/* process line in buf */
}
Example reading white space delimited words
char buf[1024];
while (scanf("%s", buf) != EOF) {
/* process word in buf */
}