Percent code for file name in C [duplicate] - c

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Getting Filename from file descriptor in C
Is there a simple and (reasonably) portable way of getting the filename from a FILE*?
I open a file using f = fopen(filename, ...) and then pass down f to various other functions, some of which may report an error. I'd like to report the filename in the error message but avoid having to pass around the extra parameter.
I could create a custom wrapper struct { FILE *f, const char *name }, but is there perhaps a simpler way? (If the FILE* wasn't opened using fopen I don't care about the result.)

On some platforms (such as Linux), you may be able to fetch it by reading the link of /proc/self/fd/<number>, as so:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
char path[1024];
char result[1024];
/* Open a file, get the file descriptor. */
FILE *f = fopen("/etc/passwd", "r");
int fd = fileno(f);
/* Read out the link to our file descriptor. */
sprintf(path, "/proc/self/fd/%d", fd);
memset(result, 0, sizeof(result));
readlink(path, result, sizeof(result)-1);
/* Print the result. */
printf("%s\n", result);
}
This will, on my system, print out /etc/passwd, as desired.

It's a bit difficult, because a FILE* can read/write from a file handle which isn't associated with a named file at all (for example an unnamed pipe or a socket). You can obtain the file handle with fileno() and then there are system specific ways to learn about the file name. Here's a discussion on how to do this under Linux:
Getting Filename from file descriptor in C
and under Windows this isn't much easier either:
http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx (as an extra step here, you use _get_osfhandle() to get the Windows file handle from the c-library file descriptor)

Related

How can I delete all the text from text file in c? [duplicate]

This question already has answers here:
How do I clear the whole contents of a file in C?
(6 answers)
Closed 4 years ago.
given argument fd in type of FILE* , for example:
FILE* fd = fopen("a.txt","w").
How can I delete all the text that writed in a.txt?
NOTE: I don't know what is the name of the file (I am write a function that gets argument in type of FILE* that someone already opened in the main).
For example:
FILE* fd = fopen("a.txt","w");
assert(fd != NULL); // it's not important for this question.
fprintf(fd,"hello1\n");
fprintf(fd,"hello2\n");
//.... and now I want to remove all the text from a.txt. How can I do it?
// The cleaning will be in other function that get just fd (without the
// name of the file)
fclose(fd);
You can open it with the write flag
fopen(filename, "w")
the file would be overwritten with a new empty file if already exists.
You can use the ftruncate function to truncate an open file. Documentation here:
https://linux.die.net/man/2/truncate
ftruncate(fileno(fd), 0);
There is no portable way of doing this in C.
In C, the interactions with files are via streams, and no facility exists to remove something from a stream as that makes no real sense. A FILE* is a pointer to an intentionally opaque structure.
I'd be tempted to deal with this at the calling site that sets the FILE* in the first place.
Either close and reopen the file (as suggested in Kira Sama's answer), or, on POSIX systems use truncate(2)
However, if you do that, the FILE* handle is out of sync (and you need to at last fflush(3) -bercause FILE* are buffered- before the truncate, and not use the same FILE* without any freopen(3)...). With pure standard C11 (see n1570) there is no way of doing what you want.
In practice, if you use truncate, you should avoid <stdio.h> functions and use read(2) and write(2) directly.
Perhaps higher level libraries like sqlite or gdbm could interest you.
I don't know what is the name of the file (I am write a function that gets argument in type of FILE* that someone already opened in the main).
Then I believe you should not do what you want. (On some POSIX systems, you might use fileno(3) and then ftruncate, but by doing so you are violating some invariants from <stdio.h> and messing up your FILE*)
Look also into rewind(3) & fseek(3)
You can use ftruncate on most systems except Windows. Windows has the _chsize function. You have to do some preprocessor checks:
#ifdef _WIN32
#include <io.h>
#else
#include <sys/types.h>
#include <unistd.h>
#endif
int truncate_file(FILE *fp);
#ifdef _WIN32
int truncate_file(FILE *fp) {
return _chsize(_fileno(fp), 0);
}
#else
int truncate_file(FILE *fp) {
return ftruncate(fileno(fp), 0);
}
#endif
I'm not sure whether this is quite correct on Cygwin or MinGW.
However, if you want to write clean, portable code without a bunch of preprocessor use, your only option is to reopen the file:
FILE *fp;
...
fclose(fp);
fp = fopen(filename, "w");
fclose(fp);

Clearing file contents only using FILE * [duplicate]

I'm using C to write some data to a file. I want to erase the previous text written in the file in case it was longer than what I'm writing now.
I want to decrease the size of file or truncate until the end. How can I do this?
If you want to preserve the previous contents of the file up to some length (a length bigger than zero, which other answers provide), then POSIX provides the truncate() and ftruncate() functions for the job.
#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);
The name indicates the primary purpose - shortening a file. But if the specified length is longer than the previous length, the file grows (zero padding) to the new size. Note that ftruncate() works on a file descriptor, not a FILE *; you could use:
if (ftruncate(fileno(fp), new_length) != 0) ...error handling...
However, you should be aware that mixing file stream (FILE *) and file descriptor (int) access to a single file is apt to lead to confusion — see the comments for some of the issues. This should be a last resort.
It is likely, though, that for your purposes, truncate on open is all you need, and for that, the options given by others will be sufficient.
For Windows, there is a function SetEndOfFile() and a related function SetFileValidData() function that can do a similar job, but using a different interface. Basically, you seek to where you want to set the end of file and then call the function.
There's also a function _chsize() as documented in the answer by sofr.
In Windows systems there's no header <unistd.h> but yet you can truncate a file by using
_chsize( fileno(f), size);
That's a function of your operating system. The standard POSIX way to do it is:
open("file", O_TRUNC | O_WRONLY);
If this is to run under some flavor of UNIX, these APIs should be available:
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
According to the "man truncate" on my Linux box, these are POSIX-conforming. Note that these calls will actually increase the size of the file (!) if you pass a length greater than the current length.
<edit>
Ah, you edited your post, you're using C. When you open the file, open it with the mode "w+" like so, and it will truncate it ready for writing:
FILE* f = fopen("C:\\gabehabe.txt", "w+");
fclose(file);
</edit>
To truncate a file in C++, you can simply create an ofstream object to the file, using ios_base::trunc as the file mode to truncate it, like so:
ofstream x("C:\\gabehabe.txt", ios_base::trunc);
If you want to truncate the entire file, opening the file up for writing does that for you. Otherwise, you have to open the file for reading, and read the parts of the file you want to keep into a temporary variable, and then output it to wherever you need to.
Truncate entire file:
FILE *file = fopen("filename.txt", "w"); //automatically clears the entire file for you.
Truncate part of the file:
FILE *inFile("filename.txt", "r");
//read in the data you want to keep
fclose(inFile);
FILE *outFile("filename.txt", "w");
//output back the data you want to keep into the file, or what you want to output.

How can I get a file pointer ( FILE* ) of known file in a specific path?

to read/write a file i need file pointer in language C in Unix environment.
I know a file name and path, but how to get file pointer using its name and path.
#include <stdio.h>
FILE * pFile;
pFile = fopen ("myfile.txt","w");
Import the standard input/output header like so
#include <stdio.h>
And then create a pointer for the file you want to open.
FILE * file_pointer;
file_pointer = fopen ("[path to file]","w");
fclose(file_pointer);
NOTE: Specify whole path to file if it is not in the same directory as your source file.
Dont forget to close the file after you have done the operations you need
According to the post from ssmithstone:
#include <stdio.h>
FILE * pFile;
/* open file and check if was successful */
if ((pFile = fopen("myfile.txt", "w")) == NULL)
{
/* couldn't open file; do some error handling if u want */
}
else
{
/* do s.th. */
/* close file */
fclose(pFile);
}
In this case w means writing. For other options check the link posted by Yu Hao.
Seems like you are new in C programming, I've written a C program for you, you can analyse it and I believe it will be definitely helpful to you.
#define size 50
#include <stdio.h>
int main()
{
char name[size];
FILE *file;
file = fopen("your_file.txt","w");
printf("Please enter your first name\n");
scanf("%s",name);
fprintf(file,"%s",name);
fclose(file);
return 0;
}
Details:
In line 7 the second parameter w is used as file open mode - with write privileges.
The file pointer is used to create / open a file with name "your_file.txt".
function fprintf() is same as printf() function but it writes not on console but to your file.
finally we need to close the file writing operations thus we use fclose() function
Update:
To specify your path you can write your file path with your filename.fileextension
for example: You can write it as
file = fopen("/home/depthgr8/Desktop/your_file.txt","w");
This will create your_file.txt in given path if your path exists otherwise it will throw a runtime exception - segmentation fault (core dumped)

Is there a way to get the filename from a `FILE*`? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Getting Filename from file descriptor in C
Is there a simple and (reasonably) portable way of getting the filename from a FILE*?
I open a file using f = fopen(filename, ...) and then pass down f to various other functions, some of which may report an error. I'd like to report the filename in the error message but avoid having to pass around the extra parameter.
I could create a custom wrapper struct { FILE *f, const char *name }, but is there perhaps a simpler way? (If the FILE* wasn't opened using fopen I don't care about the result.)
On some platforms (such as Linux), you may be able to fetch it by reading the link of /proc/self/fd/<number>, as so:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
char path[1024];
char result[1024];
/* Open a file, get the file descriptor. */
FILE *f = fopen("/etc/passwd", "r");
int fd = fileno(f);
/* Read out the link to our file descriptor. */
sprintf(path, "/proc/self/fd/%d", fd);
memset(result, 0, sizeof(result));
readlink(path, result, sizeof(result)-1);
/* Print the result. */
printf("%s\n", result);
}
This will, on my system, print out /etc/passwd, as desired.
It's a bit difficult, because a FILE* can read/write from a file handle which isn't associated with a named file at all (for example an unnamed pipe or a socket). You can obtain the file handle with fileno() and then there are system specific ways to learn about the file name. Here's a discussion on how to do this under Linux:
Getting Filename from file descriptor in C
and under Windows this isn't much easier either:
http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx (as an extra step here, you use _get_osfhandle() to get the Windows file handle from the c-library file descriptor)

How to truncate a file in C?

I'm using C to write some data to a file. I want to erase the previous text written in the file in case it was longer than what I'm writing now.
I want to decrease the size of file or truncate until the end. How can I do this?
If you want to preserve the previous contents of the file up to some length (a length bigger than zero, which other answers provide), then POSIX provides the truncate() and ftruncate() functions for the job.
#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);
The name indicates the primary purpose - shortening a file. But if the specified length is longer than the previous length, the file grows (zero padding) to the new size. Note that ftruncate() works on a file descriptor, not a FILE *; you could use:
if (ftruncate(fileno(fp), new_length) != 0) ...error handling...
However, you should be aware that mixing file stream (FILE *) and file descriptor (int) access to a single file is apt to lead to confusion — see the comments for some of the issues. This should be a last resort.
It is likely, though, that for your purposes, truncate on open is all you need, and for that, the options given by others will be sufficient.
For Windows, there is a function SetEndOfFile() and a related function SetFileValidData() function that can do a similar job, but using a different interface. Basically, you seek to where you want to set the end of file and then call the function.
There's also a function _chsize() as documented in the answer by sofr.
In Windows systems there's no header <unistd.h> but yet you can truncate a file by using
_chsize( fileno(f), size);
That's a function of your operating system. The standard POSIX way to do it is:
open("file", O_TRUNC | O_WRONLY);
If this is to run under some flavor of UNIX, these APIs should be available:
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
According to the "man truncate" on my Linux box, these are POSIX-conforming. Note that these calls will actually increase the size of the file (!) if you pass a length greater than the current length.
<edit>
Ah, you edited your post, you're using C. When you open the file, open it with the mode "w+" like so, and it will truncate it ready for writing:
FILE* f = fopen("C:\\gabehabe.txt", "w+");
fclose(file);
</edit>
To truncate a file in C++, you can simply create an ofstream object to the file, using ios_base::trunc as the file mode to truncate it, like so:
ofstream x("C:\\gabehabe.txt", ios_base::trunc);
If you want to truncate the entire file, opening the file up for writing does that for you. Otherwise, you have to open the file for reading, and read the parts of the file you want to keep into a temporary variable, and then output it to wherever you need to.
Truncate entire file:
FILE *file = fopen("filename.txt", "w"); //automatically clears the entire file for you.
Truncate part of the file:
FILE *inFile("filename.txt", "r");
//read in the data you want to keep
fclose(inFile);
FILE *outFile("filename.txt", "w");
//output back the data you want to keep into the file, or what you want to output.

Resources