I am trying to write a simulation program in C where I am appending a file by opening it in append mode. This file is a csv (comma separated values).
I would like to write the headings of my simulation information before I write the actual values so that they don't seem unrelated. Is there an easy way to do this?
For example:
Central Node, System Delay, Bandwidth Requirement
14,240,11
4,285,23
13,300,9
My code looks like this:
void Data_Output(FILE *fp){
struct stat buf;
FILE fd = *fp;
fstat(fd, &buf);
fprintf(stderr,"DEBUG------%d\n",buf.st_size);
}
The output error I get is:
ff.c: In function ‘Data_Output’:
ff.c:296:2: error: incompatible type for argument 1 of ‘fstat’
fstat(fd, &buf);
^
In file included from /usr/include/stdio.h:29:0,
from ff.c:1:
/usr/include/sys/stat.h:148:5: note: expected ‘int’ but argument is of type ‘FILE’
int _EXFUN(fstat,( int __fd, struct stat *__sbuf ));
^
Makefile:7: recipe for target 'ff.o' failed
make: *** [ff.o] Error 1
What am I doing wrong? Should I be typecasting it in order to make it work?
You can check size of a file.
For more info how to get size you can check check this post
You can use the fstat() function to dump the stats to a buffer, which would contain the size of the file under st_size.
fstat() works on an integer low level file descriptor, not a FILE * / stream. You need to obtain the descriptor from the FILE * (fp) and use that.
Try:
int fd = fileno(fp);
fstat(fd, &buf);
Related
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)
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.
I thought I understood fstat, I was wrong.
I need to know the size of the file then read from the file.
fileN Has the path of the file and the name of the file. It looks like this. 0.txt
struct stat fileStat;
FILE *fp;
int fd = 0;
int i;
for(i = 0; i < 100; i++)
{
fp = fopen(fileN, "r");
fd = open(fileN, "r"); // I think this is eating my files and making them 0 size.
fstat(fd, $fileStat);
printf("%d", fileStat.st_size);
fclose(fp);
}
Why do I need to use fd = open(fileN, "r"); To use fstat? It feels like I am opening the file twice.
If fileStat is a struct why do I use fileStat.st_size instead of fileStat->st_size like I do when I create my own structs? Example: myString->characters;
And why is the code above printing 0s when printf is executed? And yes the files have a size bigger than 0 and I have the correct file name and path.
All code above is my interpretation of code that was Googled and mixed with my trial and error implementation. That's why I have so many questions.
EDIT: SOLUTION: open() was being called wrong and affecting the files.
Why do I need to use fd = open(fileN, "r"); To use fstat? It feels like I am opening the file twice.
Because fstat() requires a file descriptor. You could use stat() instead, which takes a filename. Or you could use fd = fileno(fp) to get the file descriptor from the stdio FILE.
BTW, you need to call close(fd) in the loop.
If fileStat is a struct why do I use fileStat.st_size instead of fileStat->st_size like I do when I create my own structs? Example: myString->characters;
You use -> when the variable on the left is a pointer to a struct, you use . when it's the struct itself. This is basic C syntax, nothing specific to fstat.
And why is the code above printing 0s when printf is executed? And yes the files have a size bigger than 0 and I have the correct file name and path.
You're not calling open() correctly. The second argument is supposed to be an int containing flags. Since you give a string instead, the pointer to the string is being coerced to an int, and the bits in this are probably not valid open flags. You need to check the return value of open to see if it succeeded -- it will return -1 if there's an error. Similarly with fstat -- it's probably returning an error because fd is not valid.
Given a struct file, is it possible to get the associated file descriptor in linux kernel space? I am trying to change permissions using either sys_chmod or sys_fchmod. One takes a file descriptor the other expects a filename from user space. I can figure out how to get the filename but how would I cast it to a user space pointer?
Thanks
The function you're after is chmod_common:
static int chmod_common(struct path *path, umode_t mode)
Which takes a path and the mode you want to set. Unfortunately, as you noticed, it's static and obviously not exported. So you could go multiple ways:
Replicate whatever it does in a function of your own
Get "the file descriptor" from struct file (ugly)
Find a way to call sys_chmod
Now sys_chmod expects a user pointer but you're in the kernel. Here's what you could do to trick it:
mm_segment_t oldfs = get_fs();
char __user *userptr;
userptr = (char __user __force *) kernptr;
set_fs(KERNEL_DS);
/* call sys_chmod */
set_fs(oldfs);
All this is very much in line with "things you never should do in the Kernel".
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)