How to pass file pointer to a function in c - c

I want to pass the file pointer as an argument to view function. And then I want to get the output the data on file from the view function. But every time telling me file not found.
#include<stdio.h>
void view(FILE *file){
char c;
file=fopen(file,"r");
if(file==NULL){
printf("file not found");
}
else{
while(!feof(file)){
c=fgetc(file);
printf("%c",c);
}
fclose(file);
}
}
int main(){
FILE *file;
file=fopen("hello.txt","w");
char s[]="hello world";
fprintf(file,"%s",s);
fclose(file);
printf("Enter 1 to read file");
int n;
scanf("%d",&n);
if(n==1)
view(file);
return 0;
}

Your error is here:
file=fopen(file,"r");
Use something like this:
file=fopen("file name","r");

As already stated in the comments, and in this answer, the fopen argument is wrong, you pass a pointer to file when you should pass the file path.
Other than that you could refactor your code so that you wouldn't have to close and reopen the file:
void view(FILE *file)
{
// the file is already opened, no need to reopen it
int c;
while ((c = fgetc(file)) != EOF) // better read routine
{ // you could also use fgets to read the whole line
printf("%c", c);
}
fclose(file);
}
int main()
{
FILE *file;
file = fopen("hello.txt", "w+"); // open to write and read
int n;
char s[] = "hello world";
if (file == NULL)
{
printf("file not found"); // perror("fopen"); would be better
return EXIT_FAILURE; // #include <stdlib.h>
}
fprintf(file, "%s", s);
printf("Enter 1 to read file: ");
if (scanf("%d", &n) == 1)
{
if (n == 1)
{
rewind(file); // reset file pointer offset to the beginning
view(file);
}
}
}

Related

Why is this function not copying the input file?

I'm just getting started into file I/O and am trying to build a function that will simply copy a file to destination.
This program compiles however an empty file is created and nothing is copied. Any advice?
#include <stdio.h>
int copy_file(char FileSource[], char FileDestination[]) {
char content;
FILE *inputf = fopen(FileSource, "r");
FILE *outputf = fopen(FileDestination, "w");
if (inputf == NULL)
;
printf("Error: File could not be read \n");
return;
while ((content = getc(inputf)) != EOF) putc(content, inputf);
fclose(outputf);
fclose(inputf);
printf("Your file was successfully copied");
return 0;
}
int main() {
char inputname[100];
char outputname[100];
printf("Please enter input file name: \n");
scanf("%s", &inputname);
printf("Please write output file name: \n");
scanf("%s", &outputname);
copy_file(inputname, outputname);
return 0;
}
There are few bugs in the code you mentioned. These two below statement
scanf("%s", &inputname);
scanf("%s", &outputname);
Are wrong as inputname and outputname are char array and array name itself address so you no need to give &inputname to scanf(). For e.g
scanf("%s",inputname);
scanf("%s",outputname);
Also ; at the end of if statement is not serving correct purpose as you expected.
This
if(inputf == NULL);
Should be
if(inputf == NULL){
/*error handling */
}
As pointed by other, getc() returns int not char. From the manual page of getc()
int getc(FILE *stream);
And this
putc(content, inputf);
Change to
putc(content, outputf); /* write the data into outputf */
Your line :
putc(content, inputf);
needs to change to
putc(content, outputf);
This code has a lot of problems:
if(inputf == NULL);
printf("Error: File could not be read \n");
return;
It is the equivalent of
if(inputf == NULL)
{
;
}
printf("Error: File could not be read \n");
return;
You have a stray ; that terminates you if statement, and whitespace doesn't matter much at all with C.
So your if statement does nothing, and your code will always emit the "Error: File could not be read" message and return without doing anything else.
What you probably want:
if(inputf == NULL)
{
printf("Error: File could not be read \n");
return;
}
This is a perfect example of why a lot of C programmers always use braces after if statements. ALWAYS.
There are multiple problems in your code:
content must be declared as int: getc() returns an int with the value of the byte read from the file or the special negative value EOF at end of file. Storing that to a char variable loses information, making the test for EOF either ambiguous (if char is signed) or always false (if char is unsigned by default).
you should pass outputf to putc.
you should return from the copy_file function if fopen fails to open either file.
you should pass the maximum number of characters to read for the filenames
you should check the return value of scanf() to avoid undefined behavior on invalid input.
Here is a corrected version:
#include <stdio.h>
int copy_file(const char *FileSource, const char *FileDestination) {
int content;
FILE *inputf, *outputf;
if ((inputf = fopen(FileSource, "r")) == NULL) {
printf("Error: cannot open input file %s\n", FileSource);
return -1;
}
if ((outputf = fopen(FileDestination, "w")) == NULL) {
printf("Error: cannot open output file %s\n", FileDestination);
fclose(inputf);
return -1;
}
while ((content = getc(inputf)) != EOF)
putc(content, inputf);
fclose(outputf);
fclose(inputf);
printf("Your file was successfully copied");
return 0;
}
int main() {
char inputname[100];
char outputname[100];
printf("Please enter input file name: \n");
if (scanf("%99s", inputname) != 1)
return 1;
printf("Please write output file name: \n");
if (scanf("%99s", &outputname) != 1)
return 1;
copy_file(inputname, outputname);
return 0;
}
Use sendfile() is more simple and efficient for copying file. You can view more detail about sendfile() by man sendfile.
#include <stdio.h>
#include <string.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
if (argc < 3)
{
printf("Usage: %s <srcfile> <dst_file>\n", argv[0]);
return 1;
}
char *src_file = argv[1];
char *dst_file = argv[2];
int src;
int dst;
ssize_t size;
struct stat stat_buf;
if ((src = open(src_file, O_RDONLY)) < 0)
{
printf("Can not open %s\n", src_file);
return -1;
}
if (fstat(src, &stat_buf) < 0)
{
printf("Can stat %s\n", src_file);
close(src);
return -2;
}
if ((dst = open(dst_file, O_CREAT|O_WRONLY, stat_buf.st_mode)) < 0)
{
printf("Can not open %s\n", dst_file);
return -1;
}
if ((size = sendfile(dst, src, NULL, stat_buf.st_size)) < 0)
{
printf("Fail to copy file, size: %ld\n", size);
}
else
{
printf("Success, size: %ld\n", size);
}
close(src);
close(dst);
return 0;
}

Better way to convert string to integer

I wrote this code to read a variable in a .txt file, ignore the first character and convert into a integer.It works but looks dumb, is there a better way to do this? I'm using just one string here but it's supposed to work with four.
void read(char a[])
{
int i;
char a1[3];
for (i = 0; i<3; ++i){
a1[i]= a[i+1];
}
int b1 = atoi(a1);
}
int main()
{
FILE *file;
file = fopen( "file.txt", "r");
if (file == NULL) {
printf( "Arquivo nao encontrado\n");
}
char a[4];
fscanf(file, "%s\n",&a);
read(a);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char filename[] = "file.txt";
FILE *fp = fopen(filename, "r");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
return(EXIT_FAILURE);
}
int value;
if (fscanf(fp, "%*c%d", &value) != 1)
{
fprintf(stderr, "Failed to read integer value from file %s\n", filename);
fclose(fp);
return EXIT_FAILURE;
}
printf("Read %d\n", value);
fclose(fp);
return 0;
}
The %*c reads a single character but does not assign it. The * to suppress an assignment is a general mechanism in the scanf()
family of functions.
Untested code.

Pass stream by reference

I am suppose to pass stream, which is a pointer, by reference. So I am passing this as a pointer to a pointer. Can someone please verify my code?
int main(int argc, char** argv)
{
FILE *stream;
printf("LINES: %d\n",scan(stream));
}
int scan(FILE *(*stream))
{
stream = fopen("names.txt", "r");
int ch = 0, lines=0;
while (!feof(*stream))
{
ch = fgetc(*stream);
if (ch == '\n')
{
lines++;
}
}
fclose(*stream);
return lines;
}
No output received.
Your code has design issues. What exactly do you want to achieve?
If you just want to count the lines, make the FILE * local to your function:
int count_lines(const char *filename)
{
FILE *stream = fopen(filename, "r");
int lines = 0;
while (1) {
int c = fgetc(stream);
if (c == EOF) break;
if (c == '\n') lines++;
}
fclose(stream);
return lines;
}
If you want to do a regular file operation (read, write, seek, rewind etc.) to a file that has already been opened with fopen, just pass the handle as FILE *:
int fget_non_space(FILE *stream)
{
int c;
do {
c = fgetc(stream);
} while (isspace(c));
return c;
}
In that case, both fopen and fclose are called outside this function. (You don't call fclose in your program, which you should, even if the operating system makes sure to close the file automatically after exiting.)
Passing a pointer to the file handle, FILE **, makes sense only if you want to change that file handle itself in the function, for example by calling fopen:
int fopen_to_read(FILE **FILE pstream, const char *fn)
{
*pstream = fopen(fn, "r");
return (*pstream != NULL) ? 0 : -1;
}
Even then, it would be better to return the file handle, as fopen does.
Your example code leaves the open filehandle accessible in main, but you don't do anything with it, you don't even close it. Is that what you want? I doubt it.
Use
int scan(FILE **stream) //no need for brackets
{
*stream = fopen("names.txt", "r"); //* is for dereferencing
if(*stream==NULL) // Checking the return value of fopen
{
printf("An error occured when opening 'names.txt'");
return -1;
}
int ch = 0, lines=0;
while ((ch = fgetc(*stream))!=EOF) //while(!feof) is wrong
{
if (ch == '\n')
{
lines++;
}
}
fclose(*stream); // Close the FILE stream after use
return lines;
}
int main(void)
{
FILE *stream;
printf("LINES: %d\n",scan(&stream)); //Pass address of `stream`. The address is of type `FILE**`
}
Replace
stream = fopen("names.txt", "r");
with
*stream = fopen("names.txt", "r");
Also
printf("LINES: %d\n",scan(stream));
with
printf("LINES: %d\n",scan(&stream));

How to see if the first character of an inputfile is a number? C programming

void main()
{
FILE *fp1;
char ch;
int count = 0;
fp1 = fopen("Text.txt","r");
if(fp1==NULL){
printf("Failed to open file. Bye\n");
exit(1);
}
printf("Text file exists");
fclose(fp1);
}
example of an input file(Text.txt)-
3
nameA
nameB
nameC
I would like to check if the very first character of this input file is a number. If its missing a number than program will stop
Include ctype.h and then there are functions that do type checks. Alternatively check if the value of the char is in the appropriate ASCII range.
This would solve your problem
void main()
{
FILE *fp1;
char ch;
int count = 0;
fp1 = fopen("Text.txt","r");
if(fp1==NULL){
printf("Failed to open file. Bye\n");
exit(1);
}
printf("Text file exists");
ch = fgetc(fp1);
if (ch < '0' || ch > '9') {
fclose(fp1);
printf("Exit: First character is not a number\n");
return; // first character of the input file is not number so exit
}
fclose(fp1);
}
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp1;
char ch, line[128];
int count = 0, num;
fp1 = fopen("Text.txt","r");
if(fp1==NULL){
printf("Failed to open file. Bye\n");
exit(1);
}
printf("Text file exists\n");
if(fgets(line, sizeof(line), fp1)){
if(1==sscanf(line, "%d", &num)){
while(num-- && fgets(line, sizeof(line), fp1)){
printf("%s", line);
}
} else {
printf("The beginning of the file is not numeric. Bye\n");
exit(1);
}
} else {
printf("No contents of the file. Bye\n");
exit(1);
}
fclose(fp1);
return 0;
}

reading a .txt file, C

I am trying to parse through a line a line of text from a .txt file and set it to a string. It is parsing most of the lines, except for the first 4 characters. This is what I'm trying to parse:
12X6 de8 dw3 ds5 g8,7 m3,4 p2,2 h2,2
And this is my code:
FILE * rooms;
int i;
char c;
char roomString[ROOM_STRING_LENGTH];
rooms = fopen("assets/rooms.txt", "r");
if(rooms == NULL)
{
printf("error opening file\n");
}
fscanf(rooms, "%s", roomString);
while((c=fgetc(rooms))!='\n')
{
roomString[i] = c;
i++;
}
printf("%s\n", roomString);
Your fscanf() call consumes the first word of the input. Remove that call.
if(rooms == NULL)
{
printf("error opening file\n");
}
//fscanf(rooms, "%s", roomString);
while((c=fgetc(rooms))!='\n')
Why do you do fscanf when you are doing fgetc. This fscanf increments the file pointer to the next word. Remove the fscanf and execute your code with the mentioned changes.
#include<stdio.h>
#define ROOM_STRING_LENGTH 50
void main(){
FILE* rooms;
int i =0;
char c;
char roomString[ROOM_STRING_LENGTH];
rooms = fopen("rooms.txt", "r");
if(rooms == NULL)
{
printf("error opening file\n");
}
//fscanf(rooms, "%s", roomString);
//printf("%s\n", roomString);
while((c=fgetc(rooms))!='\n')
{
roomString[i] = c;
i++;
}
roomString[i] ='\0';
printf("%s\n", roomString);
}

Resources