Read access violation error on trying to open a file - c

I am trying to check if a file exists by opening it with fopen() and then checking if the function returns NULL. But when I run the code, it says a read access violation error accured, but I don't get why, since I checked and the file I am trying to read is txt and has text already written in it. Can someone explain why and how I can fix it?
int main(int argc, char** argv)
{
int quit = FALSE;
if (fopen(*(argv+2), 'r') == NULL)
{
printf("Invalid input! File does not exit.");
quit = TRUE;
}
}

First, from the fopen manual, we can see that the function signature is:
FILE *fopen(const char *pathname, const char *mode);
What this means is that it will return a pointer of type FILE, and expects two arguments, both pointers to char. The second argument you pass to fopen in your code is a char, not a char*, so we need to fix that. Also, store the returned fopen pointer, as you should use it to close the file after you're done with it.
So, your code would be something like:
FILE *fp;
if ((fp = fopen(argv[2], "r")) == NULL) {
printf("File does not exist!\n");
exit(0);
} else {
/* file exists... do stuff */
fclose(fp);
}

Related

Problems with if ....==NULL in C

I have this code, note that it is shortened down. The problem is if the file exists
it still overwrites it. Been 30 years since I did any programming so bear with me. Thanks!
FILE *openFil(FILE *open, char namn[]);
int main(int argc, const char * argv[])
{
FILE *openFil(FILE *open, char namn[]);
FILE *anmal =NULL;
char filNamn[] = "ANMAL.DAT";
postTypAnm pAnm;
anmal = openFil(anmal, filNamn);
}
FILE *openFil(FILE *pointer, char name[])
{
if ((pointer =fopen(name, "r+b"))== NULL)
if ((pointer =fopen(name, "w+b"))== NULL)
{
/* It Enters here as well, but it should not do that or????? */
printf("error\n");
exit(0);
}
return pointer;
}
If you're using the C11 standard you can use the "x" argument to specify that if the file exists the fopen() function will fail.
For reference: http://www.cplusplus.com/reference/cstdio/fopen/
Here's a working example.
#include <errno.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
bool openFile(FILE **ptr,
const char *fileName);
int main(int argc, const char * argv[]) {
FILE *anmal = NULL;
const char *fileName = "ANMAL.DAT";
if(!openFile(&anmal, fileName)) {
exit(EXIT_FAILURE);
}
}
bool openFile(FILE **ptr,
const char *fileName)
{
*ptr = fopen(fileName, "w+bx");
if(!*ptr) {
perror("Error opening file: ");
return false;
}
return true;
}
This is using the x extension in GNU C to test whether the file exists.
As other people have pointed out, there are numerous problems in your original code.
You've redeclared the function prototype for openFil within main.
In openFil there's no point in both accepting the FILE pointer as
a parameter and overwriting it with the return value. Especially if
you're expecting to input a NULL pointer and use the function to
initialise it. Either use a pointer-to-pointer as a parameter so you
can modify the pointer within the function, or ignore it completely
and set its value with the function's return value. Not both.
You're not actually testing for whether the file exists at all. According to the manual pages for fopen (man fopen) neither of the flags you used in opening the file (r+ and w+) care whether the file exists. r+ opens for reading/writing and always positions the stream at the beginning of the file. w+ opens for reading/writing, truncating the file if it exists already. This explains why you didn't get the effect you intended.
1.
"It Enters here as well, but it should not do that or?????"
No, It shouldn´t. If both pointers are NULL the opening of the streams to ANMAL.DAT were not successful, neither in w+b nor in r+b mode. Proof if the file really exist in the directory of the executable. Else try to use the entire path from the root directory to the file.
"The problem is if the file exists it still overwrites it."
Why do you know that the file is really overwritten in a proper manner?
Since if ((pointer =fopen(name, "r+b")) == NULL) and if ((pointer = fopen(name, "w+b"))== NULL) both fail, it seems that the ANMAL.DAT does not exist where fopen() searches for it or otherwise an error occurs when trying to open it (maybe has incorrect format or is corrupted?).
Place perror(name) in the error routine to check if errno was set to indicate an error at name.
2.
In the error routine: exit(0) is not correct if an error has happened. Use exit(EXIT_FAILURE).
Side note:
You have another prototype for the function openFil-> FILE *openFil(FILE *open, char namn[]); inside of main, which is redundant.
Also the identifier of the second parameter is different in the prototype before main to the identifier at the definition of openFil, namn in comparison to name.

Segmentation fault when not specifying input file on command line

I am writing a program that reads from a file passed as an arguement, or reads from stdin if no arguements are given.
The code runs fine with a file passed, but I get a seg fault when no file is passed.
I basically call fopen on argv[1] if a file was given, but if no file was given I call:
f = fopen("stdin", "r");
Is this the correct syntax for opening stdin as a file?
When you start a program, the main() function is not the first thing that
get's called, quite a few things happen before the main() function is
called. One of those things is to open stdin, stdout and stderr. In
general you don't need to worry about the details how the OS does that, you
just can relay that when main() is executed, these streams are open and you
can use them.
So in your case, you can do this:
#include <stdio.h>
int main(int args, char **argv) {
FILE *fp;
if(args == 1) {
fp = stdin;
} else {
fp = fopen(argv[1], "r");
if(fp == NULL) {
fprintf(stderr, "Unable to open %s for writing\n", argv[1]);
return 1;
}
}
// do your read operations on fp
if(fp != stdin) {
fclose(fp);
}
return 0;
}
So when you call the program without arguments, stdin is used, otherwise a
file is used.
The reason why your code crashes is because
f = fopen("stdin", "r");
tries to open a file literally called stdin, which you most probably don't
have. fopen will return NULL and you probably don't check for that. If you
try to use a function that expects a FILE* pointer but pass NULL, then
you'll most likely will get a segfault.
USE f = stdin;
NOT f = fopen("stdin", "r");

How to create function that opens files and let's other functions use them? [duplicate]

This question already has answers here:
How to change value of variable passed as argument?
(4 answers)
Closed 5 years ago.
I want to create the function that opens a file and then other functions use this opened file. This is my code,
#include <stdio.h>
int openFile(FILE* inputFile)
{
inputFile = fopen("input.txt", "r");
if (inputFile != NULL)
return 0;
else
return -1;
}
void readWholeFile(FILE* inputFile)
{
char str[20];
while (feof(inputFile)) {
fscanf(inputFile, str);
printf("%s\n", str);
}
}
int main() {
FILE* inputFile;
if (openFile(inputFile) == 0) {
readWholeFile(inputFile);
}
else
printf("File didn't open");
fclose(inputFile);
return 0;
}
"File didn't open" is not printed so the file should be opened but actually readWholeFile prints nothing as a file would be empty. What's the problem?
Your prototype makes no sense, openFile() can't change the caller's FILE * when it's passed by value, you need to pass the address of the pointer in that case:
int openFile(FILE **inputFile)
{
*inputFile = fopen("input.txt", "rt");
return *inputFile == NULL ? -1 : 0;
}
But of course this serves very little purpose, just use fopen() directly where you want to open a file, instead. Returning the pointer to the open file is easier to work with, instead of having to manage a separate int that carries no added value or information (an int being 0 or -1 is not "better" than a pointer being NULL or not NULL).
You should return inputFile itself. That wauy you can reused it from other function.
Also why pass that FILE* to openFile function? It's redundant.
Design-wise you can pass the filename and the parameters like r,w etc.
FILE* openFile(const char*name, const char*params)
{
inputFile = fopen(name, params);
if (inputFile != NULL)
return inputFile;
else
return NULL;
}
But in doing that you are just abstracting out the fopen() call. You still have to check the return value of openFile(). You can use double pointer and achieve the same thing but yes I have provided with an alternative.
FILE *inputFile = openFile("input.txt","r");
if( !inputFile ){
//...
}
The thing is as far as the method shown this is really doing anything other than wrapping the fopen() call. What you can get to know from this answer that you can pass the pointer around in Functions and how to use it.
Other answer provides how you use the double pointer but do you get what happened in previous case?
You are changing the local variable that is passed to openFile(). You change it. And when the function completes then that local variable is not there anymore. It's value wont affect the FILE* variable in main().
To be clear you don't need this method to open a file. It's better if you use the 2 lines alone. Because there is no improvement whatsoever. You still have to check the return value just like you would have in case of direct fopen call.

How to read from a text file I made in C

I am new to C, I am just trying to read a simple text file I created in C. I made this file by clicking new -> empty file -> saving it to my desired location and then adding the file extension (.txt) the text file holds a sample sudoku board and the full file name is sudokuchar.txt.
The code I have to read from the file and print it is:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fpointer = fopen("sudokuchar.txt", "r");
char input[100];
while(fgets(input,100,fpointer))
{
printf("%s",input);
}
fclose(fpointer);
}
so when i compile the program does not print anything and returns -1. I assume something is wrong with the file i am trying to read from?? if some one could help it would be greatly appreciated.
Always check the return values of fopen and other standard library calls. It's most likely that your file doesn't exist. You can make a nice user friendly error message using errno, just make sure to include errno.h. Overall, your code should work, but you NEED to check the return values of things, because fopen returns NULL if it can't find the file.
FILE *fpointer = fopen("sudokuchar.txt", "r");
if(fpointer == NULL) {
fprintf(stderr, "Error: [Errno %d]: %s\n",
errno, strerror(errno));
return 1;
}
It is advisable to check what file pointer returns. If file pointer returns 0 or NULL then File pointer is unable to point to the file name you had provided. Also you can use this
File *fp = fopen(file name with full path (i.e. /home/chex/read.txt),"r")
Check man fopen
FILE *fopen(const char *path, const char *mode);

Can I pass a string into fopen()? in c

My goal is to gather input and open files based on that input.
FILE*
open_input_file (char* fileName) //opens source file to be read
{
return fopen(fileName, "r");
}
In an earlier function, I collect input from the user and save it to fileName. When I debug the program, it tells me fopen is returning NULL. That's not what I want, and I'm not sure where the problem is.
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName); // infileName is an output parameter for this
inFile = open_input_file(infileName);
}
I don't know what the problem is. Any thoughts?
If fopen returns NULL, the open failed. errno will hold the failure code and strerror(errno) will return a short description of why the open failed.
#include <errno.h>
#include <string.h>
...
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName); // infileName is an output parameter for this
if (!(inFile = open_input_file(infileName))) {
fprintf(stderr, "Error opening '%s': %s\n",
infileName, strerror(errno));
} else {
// open successful
...
}
}
Off-topic
gather_input better make sure infileName is null-terminated to prevent buffer overflows. The simplest way to do this is to define the size of the file name buffer as a macro and set the last character to 0.
#define FILENAMELEN 32
void gather_input(char infileName[]) {
...
infileName[FILENAMELEN-1]=0;
}
int main(void)
{ FILE* inFile = NULL;
char infileName[FILENAMELEN] = {'\0'};
This isn't very flexible. You could instead pass the size of the file name buffer into gather_input.
#define LENGTH(a) (sizeof(a) / sizeof(a[0]))
void gather_input(char infileName[], size_t len) {
...
infileName[len-1]=0;
}
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName, LENGTH(infileName)); // infileName is an output parameter for this
An alternative to setting the last character, if using standard string manipulation functions, is to use the strl* functions (strlcpy and strlcat) rather than their unbounded cousins. If you aren't using strl*, you should be using strncpy and strncat.
Have you checked that the file pointed to by inFilename exists on your HDD ?
Check the value of infileName in your debugger or put a printf statement to show the value on screen. printf("'%s'\n", infileName);
Did you call fclose() on your file inside the open_input_file() call. Maybe the file is still locked ?
Edit: I just checked the code. I have modified your english_to_morse() function. 1. The while statement is easier to follow than the for. 2. fgetc() returns an int and not a char.
At the top of the initialise I added this. This initialises every string in the array with and undefined string of ".??.". This will make it easier to find strange bugs as everything in your array is at least initialised.
I have modified different sections of the code but you should be able to follow.
initialize_morse_alphanum (char morseStrings[91][6])
{
for (int i=0;i<91;i++)
strcpy(morseStrings[i], ".??.");
....
....
void
english_to_morse(FILE* inputFile, FILE* outputFile, char morseStrings[91][6])
{ int convert;
convert = fgetc(inputFile);
while (convert != EOF)
{
fputs(morseStrings[convert], outputFile);
fputc(' ', outputFile);
printf ("%s ", morseStrings[convert]);
convert = fgetc(inputFile);
}
}
open_output_file (char* fileName) //opens destination file to be written
{ FILE* handle = NULL;
handle = fopen (fileName, "w"); <---- Remove the * from filename
return handle; }
Also, as mentioned in a different answer, it would be good to add some bounds checks to different areas of the code. At the moment it is quite prone to crashing. If my input file contains a lowercase 'a' (ascii 96) your program will be accessing memory that is out of bounds. So you should add a line like if (convert >= '0' && convert <= 'Z') in there somewhere. I will let you work that out.
Make sure that gather_input works properly. Could it be a problem because you're trying to read a file you're also writing on? In this case, try to close and open again the stream.

Resources