passing argument of text file from main to other function - c

How can I pass argument from cmd which is equal to the name of the file I want to open with other function than main?
I want to run program in cmd as "myprogram -open myfile.txt" just for example, and I want use another function to count characters or spaces or whatever in this file. How can I pass the name of file, which is in this case argv[2] to another function in which I can use fopen? thanks for your time.
int main(int argc, char **argv)
{
if((argc==3) && (strcmp("-open", argv[1]) == 0))
etc.

Simply pass in argv[2].
int main(int argc, char **argv)
{
if((argc==3) && (strcmp("-open", argv[1]) == 0))
{
FILE *fp = fopen(argv[2]);
//OR
otherFuncThatCallsFopen(argv[2]);
}
}
argv[2] is a valid char * that points to the 2nd argument.

You could write a function with signature like unsigned int count_characters(const char *file_name)
and call it with count_characters(argv[2])

Related

Beginner Q -ARGV and multiple files

Good afternoon, Old man trying to learn new tricks here,
I have been given an assignment that I am trying to work my way through but I am stuck as I don't fully understand the argv[]
I have 4 files I want to read from and eventually use malloc and realloc but thats further down.
My initial plan was to try read one file and get it onto the command line. I had it opening but made that many changes that now I'm lost.
Think my problem lies with argv[4] as i dont understand it, when I put 4 it goes into theloop and errors but with 1 it just bombs out.
If someone can point me in the direction I am going wrong here it would be great
Thanks
struct Person { char lname[20]; char fname[20]; int id; };
int i, N;
struct Person *student;
int main(int argc, char *argv[])
{
FILE *outputfile;
printf("Please enter the name of the file to open: ");
scanf("%s", argv[4]);
outputfile = fopen(argv[4], "r") ;
if (outputfile==NULL){
perror(argv[1]);
fprintf(stderr,"Error while opeining file\n");
exit(-1);
}
You don't have to use argv[]. Argv is an array of strings that store the arguments passed in when running the executable. If you run the executable like this: ./a.out, then argv only contains one element, which is the path of the executable itself. If you run the program like this, and you try to access argv[4], it does not give you an error, but if you debug it using GDB, it will output the following: warning: Invalid parameter passed to C runtime function.
You could pass in a file on the command line like this: ./a.out yourfile.txt. In this case, argv[0] will be the path of the executable a.out, and argv[1] will be the string "yourfile.txt".
It might be easier to completely drop the use of argv and store the user input for the filename in a string. You can then pass that string as an argument to fopen. This would look something like this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char fileName[30];
char ch;
printf("Please enter a file name\n");
scanf("%s", fileName);
FILE *outputFile = fopen(fileName, "r");
if(outputFile == NULL) {
printf("Could not open %s\n", fileName);
exit(-1);
}
}
Use constants (NAME_LEN) instead of hard-coding magic values.
Prefer multiple lines for your struct. It's easier to read and version control systems prefer lines for diffs.
Avoid global variables.
Do a boundary check using argc (count of elements in argv) before you read argv. argv[0] is the name of your program, argv[1] is the first argument.
Treat argv as read-only, i.e. don't do scanf("%s", argv[4]).
Prefer to initialize variables instead of declaring and assigning a value separately. It's easy to forget setting a variable before use which leads ot undefined behavior. Initialization might be faster, too.
Your file handle is called outputfile but with fopen() you use the mode of r for reading. Either mode should be w or you want to change the variable name to inputfile.
#include <stdio.h>
#include <string.h>
#define NAME_LEN 20
struct Person {
char lname[NAME_LEN];
char fname[NAME_LEN];
int id;
};
int main(int argc, char *argv[]) {
char filename[FILENAME_MAX];
if(argc > 4) {
strcpy(filename, argv[4]);
} else {
printf("filename? ");
fgets(filename, FILENAME_MAX, stdin);
filename[strcspn(filename, "\n")] = '\0';
}
FILE *outputfile = fopen(filename, "w");
if(!outputfile) {
// ...
}
fclose(outputfile);
}
and you would run your program with either:
$ ./a.out dummy dummy dummy output.txt
or
$ ./a.out
filename? output.txt
It sounds as if you are expected to provide 4 file names as command line parameters. In which case you should be doing this:
#include <stdio.h>
int main (int argc, char *argv[])
{
const int files = 4;
if(argc != files+1)
{
printf("Usage: myprog file1 file2 file3 file4");
return 0;
}
FILE* fp [files];
for(int i=0; i<files; i++)
{
fp[i] = fopen(argv[i+1], "r");
...
}
...
}

Can I save a .txt file passed as a command line argument to a char array in C?

I'd like to save a .txt file that I am passing as an argument into some sort of datatype. For example, if my command was ./projexec -c "some text" filename.txt, my goal is to copy the contents of filename.txt(argv[3]) into a char array. Is this possible, if so how?
int main(int argc, char *argv[]) {
int i;
FILE *fp;
char txtfile[];
for(i=0; i<argc; i++) {
if(argc>1 && argv[3] !=NULL) {
fp=fopen(argv[3],"r");
}
else {
printf("There is no .txt file in this argument.");
}
}
UPDATE: fread did the trick!
#define size 1000
int main(int argc, char *argv []) {
int i;
FILE *fp;
char argtxt[]= ".txt";
char txtfile[size];
size_t br;
for(i=0; i<argc; i++){
if(argc > 1 && strstr(argv[i],argtxt)!=NULL){
fp=fopen(argv[i],"r");
br=fread(txtfile,sizeof(txtfile),size, fp);
printf("file copied.\n");
}
}
printf(txtfile);
}
I would recommend reading about the "mmap" system call.
You need to open a file using the "open" system call,
then call "mmap" on it, which returns a pointer to a buffer (created for you by the system) so you can just treat it like a very long string.
Lines are separated with "\n" and make sure you have opened the file with writing permissions if you are planning on using "strtok" on the string.
This is due to the fact that "strtok" rewrites the delimiter to a null terminator.

How to parse command-line arguments from a separate function

I am attemping to parse a command-line argument from one function process_command_line which I will then use in a main function. The second command-line argument enables the name of a file input to be submitted, which will later be used to read/write files. For the time being, I will just print out the argument within the main function to ensure that it is functioning correctly. I have had no issues parsing integers using this separate function method, but cannot get a correct output when trying to parse an input file name.
EDIT: I think my issue lies in the second function where I have a line saying argv[1] = input_file;
My attempt:
#include <stdio.h>
#include <stdlib.h>
int process_command_line(int argc, char *argv[]); //declaration for command-line function
char str2[100];
int main(int argc, char *argv[]) {
printf("%s", str2);
getchar();
return 0;
}
//This function reads in the arguments
int process_command_line(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Error: Missing program arguments.\n");
exit(1);
}
//first argument is always the executable name (argv[0])
//second argument reads in the input file name
strcpy(str2, argv[1]); //I think this is where the problem lies
}
With the help of users on this question, here is my updated and functioning solution. The problem was that I wasn't calling the second function within my main function.
My solution:
#include <stdio.h>
#include <stdlib.h>
int process_command_line(int argc, char *argv[]); //declaration for command-line function
char str2[100];
int main(int argc, char *argv[]) {
process_command_line(argc, argv); //This was missing in my first attempt
printf("%s", str2);
getchar();
return 0;
}
//This function reads in the arguments
int process_command_line(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Error: Missing program arguments.\n");
exit(1);
}
//first argument is always the executable name (argv[0])
//second argument reads in the input file name
strcpy(str2, argv[1]);
}

Passing argument to sub-functions in C

A simple problem, but somehow I can't find the solution,
I want to pass basically, in my program one of my arguments is the desired file to send the program output to.
It's not really an issue to set it up in main() however, I'm wondering how can I process argv[] in functions that are not main.
I tried it like this:
void print_ip(struct arp* arp, char* argv[]){
char *myfile = argv[2];
if ( strlen(argv[2]) <= 0 ){
printf("ERROR: Please specify a proper interface \n");
}
else {
strcpy(myfile, argv[2]);
}
f = fopen(myfile, "w");
if (f != NULL){
printf("Found an IP address \n");
fprintf(f, "\t<ipv4>%s, %s</ipv4>", arp->ipv4_destination, arp->ipv4_source);
}
else {
printf("ERROR: Failed to open file \n");
exit(1);
}
}
This function works, only issue is when I try to launch the function from elsewhere
for example
void arp_scan(struct arp*, int bsd_socket){
... code ...
print_ip(&arp, argv);
}
i get the following error:
scanner.c: In function ‘arp_scan’: scanner.c:187:25: error: ‘argv’
undeclared (first use in this function)
print_ip(&arp, argv);
Surely there must be a way other than declaeing char *argv[] in every single function to be able to proccess it from one to another
only main can accept arguments from the command line (argv). if you want to pass these command line args to a function then you need to pass them as a paramater.
#include <stdio.h>
int passingvars(int argc, char **argv)
{
int i = 0;
while (i < argc)
{
printf(argv[i]);
i++;
}
}
int main(int argc, char *argv[])
{
passingvars(argc, argv);
return 0;
}

Why am I segfaulting?

I'm very new to C, I am attempting to read the contents of one file character by character and output them to the stream. But even with my fopen() command commented out I receive segfault (core dumped).
I must run a command: ./a.out < testWords.in > myOut.txt to execute my file properly.
Here is what I have so far:
#include <stdio.h>
void main(char *fileName[])
{
printf("filename is %s.\n",fileName[0]);
//Get file based on a string inputed
FILE *fp=fopen(fileName[0],"r"); //Fetches our file as read only
char ch;
int lineCount = 0;
int wordCount = 0;
int charCount = 0;
//Failed to find/open file. NULL character.
if (fp == 0) printf("Woops! Couldn't open file!\n");
//While not at end of file, grab next char.
else while( (ch=fgetc(fp)) != EOF)
{
if (ch == '\n') //on newline
{
//Prints (charCount,wordCount)\n lineCount:
printf("(%d,%d)%c%d:",charCount,wordCount,ch,lineCount);
charCount = 0;
lineCount += 1;
}
else printf("%c",ch); //mirrors char.
}
fclose(fp); //Closes file (gotta be tidy!)
}
You can't just invent a way to call main. You need to use one of the standard ways, like this:
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Missing filename\n");
return -1;
}
FILE *fp = fopen(argv[1], "r");
// ...
}
And note that argv[0] contains the program name (if available; if not it contains an empty string).
Your program segfaulted because you received the int argc argument into your char *filename[] parameter. If you ran the program with a single command line parameter, the value passed in as the first argument would have been 2, which is not a valid pointer value. The expression filename[0] dereferences that address and causes a segfault.
Any time you get a segfault in C, you should smell a bad pointer or address in an argument list. In this particular case., the signature of main is always int main(int argc, char** argv). Yours isn't.
What you want is
int main(int argc, char ** argv) {
...
FILE * fp = fopen(argv[1]); // Quiz: why argv[1]? What's argv[0]?
You're getting away with it in the compiler because, basically, luck.
I also notice in your example call, there's actually no argument in the argument list, because you're using redirection.
Use:
int main(int argc, char* argv[])
And use argv[1] as fileName.
Main function must receive always that two parameters.

Resources