Is it necessary to pass the file pointer to main? - c

I am quite new to C programming and I have to make a program that asks the user to enter the file name to open and then open that file and print the values sorted.
Will I need to pass the file pointer to main, or can I just open the file in one function and I can work with the file throughout the other functions?
int getFile ()
{
char file_name[100];
FILE* fp;
int rc;
printf("Enter the file name: ");
rc = scanf("%s", file_name);
if (rc != 1)
printf ("error");
fp = fopen(file_name, "r");
return 0;
}
Do I have to pass the file pointer from here to main?

Just pass the file name as an argument to main function, it maybe what you want.
You might use int main(int argc, char* argv[]), an example:
int main(int argc, char* argv[])
{
FILE* fp;
if (argc == 1)
printf("usage : a.out filename\n");
else
{
if (fp = fopen(*++argv, "r") != NULL)
{
/*your code here*/
}
}
return 0;
}

You can open the file in one function and pass it as argument to other functions. For example, for the pre-open file handle stdin, you could use it as:
char mystring [100];
fgets (mystring , 100 , pFile)

Related

File I/O Uninitialised Variable Problem - C Program

I have the following code and when I try to run it, I get the following warning:
warning: variable 'myfile' is uninitialized when used here [-Wuninitialized]
myfile = fetch_file(myfile, argc, argv);
note: initialize the variable 'myfile' to silence this warning
FILE *myfile;
I have been trying to find out how to fix the warning but haven't been successful.
#include <stdio.h>
#include <stdlib.h>
#define LINE_SIZE 300
FILE * fetch_file(FILE *myfile, int argc, char *argv[1])
{
if (argc == 1)
{
printf("Error, not enough commandline arguments.");
exit(0);
}
myfile = fopen (argv[1], "r");
if (myfile == NULL)
{
printf("\nNo file named %s was found.", argv[1]);
exit(0);
}
else
{
printf("%s was successfully opened", argv[1]);
}
return myfile;
}
void print_file(FILE *the_file, char *line, int size)
{
int count = 0;
while (fgets(line, size, the_file) != NULL)
{
printf("%s", line);
count++;
}
fclose(the_file);
printf("\nThere are %d lines\n", count);
}
int main (int argc, char *argv[])
{
FILE *myfile;
char line[LINE_SIZE];
myfile = fetch_file(--> myfile <-- , argc, argv); <----------- (warning)
print_file(myfile, line, LINE_SIZE);
return 0;
}
Ps: I'm fairly new to asking questions on this website, so if there is any way I can improve my questions and code, feel free to criticise me...
You want this:
FILE *fetch_file(int argc, char *argv[1])
{
if (argc == 1)
{
printf("Error, not enough commandline arguments.");
exit(0);
}
FILE *myfile = fopen (argv[1], "r");
...
}
int main (int argc, char *argv[])
{
FILE *myfile;
char line[LINE_SIZE];
myfile = fetch_file(argc, argv);
...
}
It is pointless to pass the myfile parameter to fetch_file.
The reason for the warning is that you pass an uninitialized value to a function:
This simple code reproduces this exact problem:
int foo(int bar)
{
bar = 2;
return bar * 2;
}
int main (int argc, char *argv[])
{
int kwork; // kwork is not initialized
foo(kwork); // here you pass an uninitialized value
// which the foo function cannot use in a useful manner
}

Arguments to open file

I want to open a file using the arguments when executing it, for example:
./Project 123.txt
I can make this work to some extent, but if I try to pass the arguments into a function, and then call the function, something is not working quite right.
Here is the function I have, which will read the lines from a text file:
int numeroLinhas(){
int ch;
FILE *fp;
int linhas=0;
fp = fopen("123.txt","r");
while( ( ch = fgetc(fp) ) != EOF ){
if(ch=='\n'){
linhas++;
}
}
fclose(fp);
fprintf(stats, "linhas: %d\n", linhas);
}
int main(int argc, char *argv[]){
FILE *fp;
fp = fopen(argv[1],"r");
numeroLinhas();
}
So, I would like to know how can I pass the argv[] has an argument into my numeroLinhas() function, so that I don't have to call the name of the file at all during the coding, just when executing.
The problem is that you have hard-coded the file name to open. Modify your function to take an argument, a string naming the file.
Then just pass the correct argv entry as the argument to the function, after checking the number of arguments to the program first.
Pass the name of the file to the function that counts the lines in the file:
#include <stdio.h>
void numeroLinhas(const char *filename)
{
int ch;
int linhas = 0;
FILE *fp = fopen(filename, "r");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
return;
}
while ((ch = fgetc(fp)) != EOF)
{
if (ch == '\n')
linhas++;
}
fclose(fp);
fprintf(stats, "linhas: %d no %s\n", linhas, filename);
}
int main (int argc, char *argv[])
{
for (int i = 1; i < argc; i++)
numeroLinhas(argv[i]);
return 0;
}
Error check fopen() calls; they fail. Handle the int returned by fgetc() correctly. Change the function to return void since there isn't a return. Report errors on standard error. Include file name in the outputs (error and routine). Invoke the function on all arguments provided. Don't say anything if no arguments are provided — or add if (argc < 2) { fprintf(stderr, "Usage: %s file [...]\n", argv[0]); return 1; } before the loop in main().
Sorry about mixed English/Portugese messages.
int numeroLinhas(char *filename){
char ch;
FILE *fp;
int linhas=0;
fp = fopen(filename,"r");
while( ( ch = fgetc(fp) ) != EOF ){
if(ch=='\n'){
linhas++;
}
}
fclose(fp);
fprintf(stats, "linhas: %d\n", linhas);
}
int main (int argc, char *argv[]){
//should have an if for argc size
char *filename = argv[1];
numeroLinhas(filename);
}

How to redirect more than one text file in c programm

How to redirect more than one text file in c program? For example I have the following C code:
//redirection.c
#include<stdio.h>
main()
{
int x,y;
scanf("%d",&x);
x=x*x;
printf("%d",x);
scanf("%d",&y);
y=x+y;
printf("%d",y);
}
After compiling this code I created two text files text1.txt having the value 8 and text2.txt having the value 6.
When I give input to this program using command line redirection (as redirection<text1.txt), it gives output 64 and does not wait to take another input (and program exits) which I want to give another input from text2.txt.
Is there any solution how can I send another input via text2.txt for second scanf function in the above program?
While giving the input as redirection as like this.
cat a b | ./a.out.
Or else you can use the command line arguments.
#include<stdio.h>
main(int argc, char *argv[])
{
FILE *fp, *fp1;
if ( (fp=fopen(argv[1],"r")) == NULL ){
printf("file cannot be opened\n");
return 1;
}
if (( fp1=fopen(argv[2],"r")) == NULL ){
printf("file cannot be opened\n");
return 1;
}
int x,y;
fscanf(fp,"%d",&x);// If you having only the value in that file
x=x*x;
printf("%d\n",x);
fscanf(fp1,"%d",&y);// If you having only the value in that file
y=x+y;
printf("%d\n",y);
}
you can also use command line arguments:
#include <stdio.h>
#define BUFSIZE 1000
int main(int argc, char *argv[])
{
FILE *fp1 = NULL, *fp2 = NULL;
char buff1[BUFSIZE], buff2[BUFSIZE];
fp1 = fopen(argv[1], "r");
while (fgets(buff1, BUFSIZE - 1, fp1) != NULL)
{
printf("%s\n", buff1);
}
fclose(fp1);
fp2 = fopen(argv[2], "r");
while (fgets(buff2, BUFSIZE - 1, fp2) != NULL)
{
printf("%s\n", buff2);
}
fclose(fp2);
}
here is a more cleaned up version:
#include <stdio.h>
#define BUFSIZE 1000
void print_content(char *file);
int main(int argc, char *argv[])
{
print_content(argv[1]);
print_content(argv[2]);
}
void print_content(char *file){
char buff[BUFSIZE];
FILE *fp = fopen(file, "r");
while (fgets(buff, sizeof(buff), fp) != NULL)
{
printf("%s\n", buff);
}
fclose(fp);
}

How do I use a text file passed in as an argument from the command line in C?

I am having the hardest time trying to figure out how to use a text file that is passed in as a command line argument. I simply dont know to get the file text into my program to be used. My code looks something like this....
char buffer[80];
int i;
int lineCount = 0;
fgets(buffer, 80, stdin); //get the first line
while (buffer != NULL) {
// do some stuff
}//end fgets while
This is for a homework assignment and I know my teacher is going to run the program with the following command:
username#mylunixbox$ ./a.out <data1> output1
data1 is the text file I am trying to use.
Use argv[1]. That will give you the file name, then you can use fopen() and use file operations to read the contents from the file.
int main(int argc, char **argv)
{
int rc = EXIT_SUCCESS;
for (int i = 1; i < argc; i++)
{
FILE *fp = fopen(argv[i], "r");
if (fp == 0)
{
fprintf(stderr, "%s: failed to open file %s for reading\n",
argv[0], argv[i]);
rc = EXIT_FAILURE;
}
else
{
char line[4096];
while (fgets(line, sizeof(line), fp) != 0)
...do stuff with the line read from the file...
fclose(fp);
}
}
return rc;
}

Why does it matter where fopen is used?

I could use some help understanding something puzzling to me. It concerns the position of of fopen() to read out a file.
Following code (C compiled with gcc 4.5.2):
#include <stdlib.h>
#include <stdio.h>
void try_fopen(FILE* f_handle, const char* f_name, const char* mode) {
f_handle = fopen(f_name, mode);
if( f_handle == NULL ) {
fprintf(stderr, "Error: Unable to open '%s'.", f_name);
exit(EXIT_FAILURE);
}
}
int cnt_ones(FILE* pFile) {
int c;
int n = 0;
do {
c = fgetc (pFile);
if (c == '1') n++;
} while (c != EOF);
return n;
}
Why is it that putting the fopen in a function gives a Segfault:
int main (int argc, char** argv) {
FILE * pFile;
try_fopen(pFile, argv[1], "r"); // Gives a Segfault
printf ("The file contains %d ones.\n", cnt_ones(pFile) );
fclose (pFile);
return 0;
}
While putting it into the main (along with the if doesn't):
int main (int argc, char** argv) {
FILE * pFile;
pFile = fopen(argv[1], "r"); // While this doesn't give a Segfault
if( pFile == NULL ) {
fprintf(stderr, "Error: Unable to open '%s'.", argv[1]);
exit(EXIT_FAILURE);
}
printf ("The file contains %d sign characters.\n", cnt_ones(pFile) );
fclose (pFile);
return 0;
}
C is pass by value, not by reference, so you need to pass the pointer to pFile, otherwise you don't change it outside of the function scope:
void try_fopen(FILE** f_handle, const char* f_name, const char* mode) {
*f_handle = fopen(f_name, mode);
if( *f_handle == NULL ) {
fprintf(stderr, "Error: Unable to open '%s'.", f_name);
exit(EXIT_FAILURE);
}
}
// ...
try_fopen(&pFile, argv[1], "r");
Because the pointer pFile is passed by value to the function try_open. The value modified inside the function is not available in the main. To solve this, you need to pass the address of the pointer to the function, so try_open would accept FILE** and assign the result of fopen to *pFile. While calling this function you should pass the address of pFile using &pFile.
You can either do :
File * fp;
try_fopen( &fp,.....); /* void try_fopen (FILE ** fp,....) */
or the following :
File * fp = try_fopen("file name"); /* FILE * try_fopen (const char * file_name,...) */
The reason is simple, when you pass FILE* to function, it's updation will be lost as it is passed by Value. Try passing FILE ** to the function and it will work. Refer to Binyamin Sharet's answer above for the code snippet
The reason for this can be understood by reading this link
Or
You can change the function try_open to return FILE * as the return value.
FILE *try_fopen(const char* f_name, const char* mode)
{
FILE *f_handle = NULL;
*f_handle = fopen(f_name, mode);
if( *f_handle == NULL )
{
fprintf(stderr, "Error: Unable to open '%s'.", f_name);
exit(0);
}
}
//In the main function.
FILE *pFile = try_fopen(argv[1], "r");

Resources