C - Using a user input file name - c

I've ran into a problem trying to open a file from user input. I can open it if the filename is correct the first time it's entered, but can't if it's correct in the while loop.
char file[256], *end;
printf("Enter the name of the file: ");
fgets(file, 256, stdin);
if((end=strchr(file, '\n'))!=NULL)
*end='\0';
FILE *fp=fopen(file, "r");
while(fp==NULL)
{
printf("The given file doesn't exist. Enter a file name: ");
fgets(file, 256, stdin);
if((end=strchr(file, '\n'))!=NULL)
*end='\0';
FILE *fp=fopen(file, "r");
}

I can open it if the filename is correct the first time it's entered, but can't if it's correct in the while loop.
No, you're being fooled. The problem is that the loop condition in while(fp==NULL) tests the value of variable fp declared outside the loop, and inside the loop you never set that variable, so if you enter the loop you will never exit.
But that doesn't mean you fail to open the file on the second attempt or a subsequent one. Inside the loop, you declare another variable fp, "shadowing" the one outside, and assign the result of fopen() to it. When this fopen() succeeds, you effectively ignore the result.
As another, now deleted, answer said, the main thing to do is to fix the loop so that it uses the same fp that is used outside. The smallest change that achieves that would yield this version of the loop:
while(fp==NULL)
{
printf("The given file doesn't exist. Enter a file name: ");
fgets(file, 256, stdin);
if((end=strchr(file, '\n'))!=NULL)
*end='\0';
fp=fopen(file, "r");
}
There are some other issues with the way you input the file name, both there and in the code preceding, as well as some unnecessary code duplication, but as long as the file names entered by the user are simple and short, that will do the trick.

You need to consider about the platform here, to make it your code cross platform file check the approach is different. If the platform is not important then you dont need to worry about Windows, in Linux you can use stat utility.
Simple way to check the existence of file(Checks in read-mode) :
int read_file_exists(const char *filename)
{
FILE *fp = fopen (filename, "r");
if (fp!=NULL) fclose (fp);
return (fp!=NULL);
}
Check this link for more information about C file check.

Related

Can't manage to open a file stream in C

I had to write a simple database (console application) in C: You could input gender, name and adress of people and the data would be saved in an array of structs called 'Person'. You could then also display all entries or delete entries again. So far so good.
Now I have to add functions to save the data into a .csv file and read from it again. However, the function fopen() always returns a NULL-pointer, so I can't even get to the reading or writing part. Below is my code. I hope you can tell me why not even this first step is working. I'm rapidly losing any confidence I had in my C abilities.
void save(Person persons[]) {
char name[LEN];
printf("File Name: ");
fgets(name, LEN, stdin);
fflush(stdin);
name[strlen(name)] = '\0';
FILE *file = fopen(name, "wx");
if (!file) {
printf("The file couldn't be created.\n\n");
}
}
why not even this first step is working.
fopen(name, "wx") certainly returns NULL as name contains '\n'. Improbable that such a file name exists.
See Removing trailing newline character from fgets() input.

fgets() not working.in C?

Edit: Deleted all but the main question.
My program here is supposed to create a file at a specified directory, and write specified text to it. A correct file's path and content should look something like this:
Path: D:\test.txt
Content: The printing succeeded.
For some reason, my code won't recognize the "path" variable. I don't know what I'm doing wrong here. The "text" variable works fine.
#include<stdio.h>
int main()
{
//Declaring variables
char path[999];
char text[999];
FILE *fp;
//prompting for path variable
printf("Specify a file path.\n");
fgets(path,999,stdin);
printf(path);
//prompting for the text variable.
printf("What do you want to write?");
fgets(text,999,stdin);
printf(text);
//opening and printing to file.
//fp = fopen("D:\\test.txt", "w");
fp = fopen(path, "w");
fprintf(fp, text);
fclose(fp);
//test print to see that the program completed correctly.
printf("\nThe printing has been done.");
return 0;
}
The thing I don't understand is that fp = fopen("D:\\test.txt", "w"); works, but fp = fopen(path, "w"); doesn't. I've tried putting in these different paths.:
D:\\test.txt
D:\test.txt
D\test.txt
D\\test.txt
It doesn't open the file when you open the variable path because fgets() reads the newline and puts it at the end of the string (if there's enough space in the buffer). In order to make it work you have to manually remove the newline from the string.
Try this before opening the file.
if(isspace(path[strlen(path)-1]))
path[strlen(path)-1]='\0';
You might also need to include <ctype.h>

Ansi C: Attempting to count total chars in a file

The task is simple but I am having an issue with the method returning 0.
This means my loop:
int getCharCount(FILE *fp) {
int c;
int i = 0;
while( (c = fgetc(fp)) != EOF) {
i++;
printf("Loop ran");
}
return i;
}
Did not run.
In my testing I found that the loop never runs because the "Loop ran" never prints. I am new to c and not sure if I am doing something wrong when trying to count chars in the file.
I feel like I should mention that the file is opened with "wb+" mode and that there are a few long methods that edit the file. Essentially before using this getCharCount() method the text file is cleared of all previous data, then user enters a number of 44 char length strings at a time and I use this method I just posted to calculate the total number of chars which will be used to navigate my display data method.
I am in a library working on this so if anything extra is needed to be posted or if anything needs to be clarified I will try to be quick with my responses. I don't want to post my whole code because there would be a chance to cheat and I need to get this done myself.
Thanks ahead.
If you write to the file and then call your method on the same file handle, the file handle is already at the end of the file so it will see EOF immediately. We would need to see more of the code to be sure I think.
So, you could rewind the file handle at the start of your function.
Or you could just call ftell to find out your offset in the file, which is the same as the number of bytes written if you truncate, write and do not rewind.
Why you have to read all bytes one by one to count them? It is much easier to do fseek( fp, 0, 2 ) to jump at end of file and get current position (file length) with ftell( fp ).
You are opening with the mode w+ which will truncate the file. From the fopen man page:
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.
You will want to open it with rb+ instead of wb+ if you are reading from a file and still want to write to it. If you have already written to it and want to read what was written, you will need to seek to the start of the file pointer.
// Both of these seek to the start
rewind(fp);
fseek(fp, 0, SEEK_SET);
If the file is not open, you could use:
off_t getFileSize(const char *filepath) {
struct stat fileStat;
stat(filepath, &fileStat);
return(fileStat.st_size);
}
If the file is open:
off_t getFileSize(int fd) {
struct stat fileStat;
fstat(fd, &fileStat);
return(fileStat.st_size);
}

Having problems with fseek() in C

So, I have this function on my program that is supposed to save a "car_str" structure into the desired place on a file specified as a parameter. But when I run it, it keeps overwriting the first slot again and again, as if fseek didn't point to the specified place on the file. Is there any problem with my code? I think it may be related with the multiplication, since without it the program does well, but I cannot point to the place I want.
void save(int car_nbr)
{
FILE *f;
f = fopen("memory.txt","wb");
if (!f)
{
printf ("error");
}
else
{
car_nbr--;
fseek(f, sizeof(struct car_str)*car_nbr, SEEK_SET);
fwrite(&car,sizeof(struct car_str),1,f);
rewind(f);
fclose(f);
printf("\nsaved");
}
}
you need to fopen with r+b.
if you fail than file not exist, so you can try use "wb"
"w" - write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.
"r+" - read/update: Open a file for update (both for input and output). The file must exist.
f = fopen("memory.txt","r+b");

Files in C, how to do input

This is my output function
void output(int n){
FILE *fp;
fp = fopen("sqrt.txt", "w");
for(int i = 1; i < n; ++i){
fprintf(fp, "%.2f\n", sqrt(i));
}
fclose(fp);
}
I'm required to make an input function (it reads the output function) that prompts the user to enter the name of the file to be opened. I need the contents of the file to be printed. If it is an invalid file name, the program should exit.
How to start this exercise?
To read a file in C, you use the fopen function almost just like what you had before, except passing it read rather than write. To read the file after it's been opened, you can use fread or fscanf. The file can be closed as usual with fclose.
If you want to read from the user rather than from a file, you can use fread with stdin instead of a file or (for the equivalent of fscanf) scanf.
fopen return a pointer that can be null: if it is, that mean your process was not able to open the file. So you have to check the return value of fopen to know if the file exist (I am not sure, but if the file exist and the return value is NULL, that means you probably have not the necessary right).
Hope it can help.

Resources