File reading synchronously in Linux C - c

Please see below code.
#include < stdio.h >
#include < fcntl.h >
#include < stdlib.h >
#include < string.h >
int main(int argc,char **argv,char **envp)
{
int fd;
size_t sz;
char filebuffer[1024];
int loop;
fd=open("sample",O_RDONLY);
if(fd==-1)
{
perror("");
exit(1);
}
loop=0;
while(++loop<300)
{
lseek(fd,0,SEEK_SET);
memset(filebuffer,0,1024);
sz=read(fd,filebuffer,1024);
printf("%d.sz=%zd\t%s\n",loop,sz,filebuffer);
sleep(1);
}
close(fd);
return 0;
}
In this code, I am able to read file. But when I am changing file (reading file "sample") at the same time during reading. Then I am not able to read the changed file. I tried O_SYNC flag too. but still, it is not working, but O_DIRECT is undefined error is coming up. How can I ensure that I am able to read changes? Second thing, but I observed, if I close and open the file reading, then I am able to read changed file.
Question:
How can I read changed file without closing and opening?

I think that you're asking the following question:
I have a program which opens a file called sample and repeatedly reads the first block of that file. That works fine. However, if I edit the file sample, for example with a text editor, then my program does not see the changes, although it will if it closes and reopens the file. How can I see the changes without closing and reopening the file?
If that's your question, then the answer is:
Sorry, you cannot, because the text editor does not modify the file. It creates a new file with the old name.
In Unix, once you open a file, it will not actually get deleted, even if its name is unlinked. If another program "deletes" the file and then creates a new file with the same name, the file you have open is no longer accessible to any other program, but it is still the same file and it will not get deleted until you close it.
Most Unix text utilities, even the ones which claim to work "in-place" (such as sed -i) really do not modify files. That includes text editors. So your program doesn't see changes in the file because the file is not changing; the name has been given to a new file.
So the only way to deal with this is to close and reopen the file. When you reopen, you will be opening the new file with the old name.

The reason for not getting updated data in file could be sync time in filesystem.
I suggest fflush() after writing in to file. This makes your cache data to be written in file.
Related discussions.
Small file not committed to disk for over a minute
Is fwrite non-blocking?

This is an adaptation of your code. It forks to create two processes. The child contains your code, substantially unchanged (different error message, file name variable, and more care with printing the filebuffer which is not null terminated). The parent writes characters (the same character, over and over) to the file.
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static char const filename[] = "sample";
int main(void)
{
int fd;
size_t sz;
char filebuffer[1024];
int loop;
switch (fork())
{
case -1:
fprintf(stderr, "Failed to fork\n");
break;
case 0:
sleep(1);
fd = open(filename, O_RDONLY);
if (fd == -1)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
exit(1);
}
loop = 0;
while (++loop < 300)
{
lseek(fd, 0, SEEK_SET);
memset(filebuffer, 0, 1024);
sz = read(fd, filebuffer, 1024);
printf("%d.sz=%zd\t%.*s\n", loop, sz, (int)sz, filebuffer);
sleep(1);
}
close(fd);
break;
default:
fd = open(filename, O_WRONLY|O_CREAT, 0644);
if (fd == -1)
{
fprintf(stderr, "Failed to create file %s for writing\n", filename);
exit(1);
}
for (loop = 0; loop < 256; loop++)
{
memset(filebuffer, (loop % 64) + 33, sizeof(filebuffer));
lseek(fd, 0L, SEEK_SET);
write(fd, filebuffer, sizeof(filebuffer));
sleep(1);
}
close(fd);
break;
}
return 0;
}
Example output:
1.sz=1024 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2.sz=1024 ################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
3.sz=1024 ################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
4.sz=1024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5.sz=1024 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
6.sz=1024 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
7.sz=1024 ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
8.sz=1024 ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
9.sz=1024 ****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
As you can see, the processes run asynchronously, so the data in the file does not always change between reads, but the process is seeing the changes.
Try running this on your computer. It should work. (Sample output from Mac OS X 10.8.5.) If it doesn't, you'll need to identify which file system type you have, but I don't think it'll be a problem.

Related

Unsupported file after duplicating it

I wrote a VERY simple program that copies all the bytes from a selected file and write them in a new/selected file.
What I want to do is duplicate 'elaborate' (encoded) file such .jpg, .png, .mp3, .exe and so on...
The program works fine (especially using simple .txt file), here is a running example:
(Wrote and compiled in windows using mingw):
C:\Users\Computer\Desktop>duplicate.exe img.jpg file.txt
Content of file.txt:
ÿØÿà JFIF ÿÛ C


If file.txt would have been substituted with <filename>.<new_file_extention>, the program would have create the new file and copied the above content inside as in:
C:\Users\Computer\Desktop>duplicate.exe img.jpg new_img.jpg
When I try to open new_img.jpg though the OS says me that the file is not supported hence cannot be opened.
My reasoning before writing the program was the following: "At bottom level any file is just a sequence of bytes, hence copying from an existing file and pasting onto a brand new/selected file will result in actually duplicating the file avoiding any type of encoding."
Here is the code:
//The program is just a test, is not a final version, hence the absence of some error handling.
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXBYTE 2500
#define RDWRMAX 1024
int main(int argc, char **argv){
int ifd, ofd, n;
char buf[MAXBYTE+1];
if((ifd = open(*++argv, O_RDONLY, 0)) == -1){
fprintf(stderr, "Unable to open '%s'.\n", *argv);
exit(EXIT_FAILURE);
}
if((ofd = open(*++argv, O_WRONLY | O_CREAT, 0)) == -1){
fprintf(stderr, "Unable to open '%s'.\n", *argv);
exit(EXIT_FAILURE);
}
while((n = read(ifd, buf, RDWRMAX)) > 0)
write(ofd, buf, n);
}
Can anyone help me understand why this is happening and maybe suggesting some possible way to solve it? This is a learning process for me, so thanks in advance for all the useful answers to this question.

Writing FILE* through pipe

I have two file open in two different processes. There's a pipe connecting the two. Is it possible to write directly from one file to another? Especially if the process reading doesn't know the size of the file it's trying to read?
I was hoping to do something like this
#define length 100
int main(){
int frk = fork();
int pip[2];
pipe(pip);
if (frk==0){ //child
FILE* fp fopen("file1", "r");
write(pip[1],fp,length);
}
else {
FILE* fp fopen("file2", "w");
read(pip[0],fp,length);
}
Is it possible to write directly from one file to another?
C does not provide any mechanism for that, and it seems like it would require specialized hardware support. The standard I/O paradigm is that data get read from their source into memory or written from memory to their destination. That pesky "memory" in the middle means copying from one file to another cannot be direct.
Of course, you can write a function or program that performs such a copy, hiding the details from you. This is what the cp command does, after all, but the C standard library does not contain a function for that purpose.
Especially if the process reading doesn't know the size of the file it's trying to read?
That bit isn't very important. One simply reads and then writes (only) what one has read, repeating until there is nothing more to read. "Nothing more to read" means that a read attempt indicates by its return value that the end of the file has been reached.
If you want one process to read one file and the other to write that data to another file, using a pipe to convey data between the two, then you need both processes to implement that pattern. One reads from the source file and writes to the pipe, and the other reads from the pipe and writes to the destination file.
Special note: for the process reading from the pipe to detect EOF on that pipe, the other end has to be closed, in both processes. After the fork, each process can and should close the pipe end that it doesn't intend to use. The one using the write end then closes that end when it has nothing more to write to it.
In other unix systems, like BSD, there's a call to connect directly two file descriptors to do what you want, but don't know if there's a system call to do that in linux. Anywya, this cannot be done with FILE * descriptors, as these are the instance of a buffered file used by <stdio.h> library to represent a file. You can get the file descriptor (as the system knows it) of a FILE * instance by a call to the getfd(3) function call.
The semantics you are trying to get from the system are quite elaborate, as you want something to pass directly the data from one file descriptor to another, without intervention of any process (directly in the kernel), and the kernel needs for that a pool of threads to do the work of copying directly from the read calls to the write ones.
The old way of doing this is to create a thread that makes the work of reading from one file descriptor (not a FILE * pointer) and write to the other.
Another thing to comment is that the pipe(2) system call gives you two connected descriptors, that allow you to read(2) in one (the 0 index) what is write(2)n in the second (the 1 index). If you fork(2) a second process, and you do the pipe(2) call on both, you will have two pipes (with two descriptors each), one in each process, with no relationship between them. You will be able only to communicate each process with itself, but not with the other (which doesn't know anything about the other process' pipe descriptors) so no communication between them will be possible.
Next is a complete example of what you try to do:
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#define length 100
#define FMT(fmt) "pid=%d:"__FILE__":%d:%s: " fmt, getpid(), __LINE__, __func__
#define ERR(fmt, ...) do { \
fprintf(stderr, \
FMT(fmt ": %s (errno = %d)\n"), \
##__VA_ARGS__, \
strerror(errno), errno); \
exit(1); \
} while(0)
void copy(int fdi, int fdo)
{
unsigned char buffer[length];
ssize_t res, nread;
while((nread = res = read(fdi, buffer, sizeof buffer)) > 0) {
res = write(fdo, buffer, nread);
if (res < 0) ERR("write");
} /* while */
if (res < 0) ERR("read");
} /* copy */
int main()
{
int pip[2];
int res;
res = pipe(pip);
if (res < 0) ERR("pipe");
char *filename;
switch (res = fork()) {
case -1: /* error */
ERR("fork");
case 0: /* child */
filename = "file1";
res = open(filename, O_RDONLY);
if (res < 0) ERR("open \"%s\"", filename);
close(pip[0]);
copy(res, pip[1]);
break;
default: /* parent, we got the child's pid in res */
filename = "file2";
res = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0666);
if (res < 0) ERR("open \"%s\"", filename);
close(pip[1]);
copy(pip[0], res);
int status;
res = wait(&status); /* wait for the child to finish */
if (res < 0) ERR("wait");
fprintf(stderr,
FMT("The child %d finished with exit code %d\n"),
res,
status);
break;
} /* switch */
exit(0);
} /* main */

Linux/ Open directory as a file

I've been reading Brian Kernighan and Dennis Ritchie - The C Programming Language and chapter 8.6 is about directory listing under UNIX OS. They say that everything and even directory is a file. This means that I should be able to open directory as a file? I've tried it using stdio functions and it didn't work. Now, I'm trying it with UNIX system functions. Of course, I'm not using UNIX, I'm using Ubuntu linux. Here is my code:
#include <syscall.h>
#include <fcntl.h>
int main(int argn, char* argv[]) {
int fd;
if (argn!=1) fd=open(argv[1],O_RDONLY,0);
else fd=open(".",O_RDONLY,0);
if (fd==-1) return -1;
char buf[1024];
int n;
while ((n=read(fd,buf,1024))>0)
write(1,buf,n);
close (fd);
return 0;
}
This writes nothing even when argn is 1 (no parameters) and I'm trying to read current directory.
Any ideas/explanations? :)
Files are also called regular files to distinguish them from special files.
Directory or not a regular file. The most common special file is the directory. The layout of a directory file is defined by the filesystem used.
So use opendir to open diretory.
Nachiket's answer is correct (as indeed is sujin) but they don't clear up the mystery as to why open works and not read. Out of curiosity I made some changes to the given code to find out exactly what was going on.
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char* argv[]) {
int fd = -1;
if (argc!=1) fd=open(argv[1],O_RDONLY,0);
else fd=open(".",O_RDONLY,0);
if (fd < 0){
perror("file open");
printf("error on open = %d", errno);
return -1;
}
printf("file descriptor is %d\n", fd);
char buf[1024];
int n;
if ((n=read(fd,buf,1024))>0){
write(1,buf,n);
}
else {
printf("n = %d\n", n);
if (n < 0) {
printf("read failure %d\n", errno);
perror("cannot read");
}
}
close (fd);
return 0;
}
The result of compiling and running this:
file descriptor is 3
n = -1
read failure 21
cannot read: Is a directory
That settles it, though I'd have expected open to fail, since the correct system function for opening directories is opendir().
Though everything in unix is a file (directory also) but still filetype is concept is present in unix and applicable to all files.
there are file types like regular file,directory etc and certain operations and functions are allowed/present for every file type.
In your case readdir is applicable for reading contents of directory.
If you want to see the files in a directory you have to use the opendir and readdir functions.
K&R were correct for the original UNIX. I remember doing it back when UNIX file systems had a 14 character length limit for filenames. The opendir(), readdir(), ... stuff happened about the time that longer file names became common (around 1990?)

access always returns -1, even when the file exists

I'm having a bit of a problem with a lab I'm working on for school.
What it's supposed to do is check to see if a file exists or not. My code works fine except one line, when I try to check to see if the file exists or not. Even if the file exists, it's returning as if it's not there always. Yet if I hard code the file name into the program it works fine. I'm just trying to figure out what's causing the file name to be interpreted wrong when I pass it into accept (or fopen I've tried both).
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
//open lab4.in
FILE *file = fopen("lab4.in", "r");
if (file == 0) {
printf("Unable to open lab4.in for reading");
exit(-1);
}
//get the file name to check
char filetocheck[120], output[12];
fgets(filetocheck, 120, file);
int i;
//open lab4.out for writing
unlink("lab4.out");
FILE *write = fopen("lab4.out", "w");
fgets(output, 12, file);
//check the file is there and write the characters to lab4.out
if (access(filetocheck, F_OK) == -1){
for (i=5; i<10; i++){
fputc(output[i], write);
}
} else {
for (i=0; i<5; i++){
fputc(output[i], write);
}
}
//close the files at the end
fclose(write);
fclose(file);
}
Okay, when an I/O operation like this fails, as well as the -1, you get a result in a global int errno;
Where you have your printf, replace that with
perror(argv[0]); /* or something else useful. See below */
and add the declaration
int errno;
between your #includes and the int main, and you'll get a useful error message.
(PS: Two things to check: make sure the file's where you expect it, and use ls -l to make sure it's readable.)
Update
Dammit, that's what I get for not checking the man page. The argument to perror is indeed a string, used to preface the error message.
In this statement:
fgets(filetocheck, 120, file);
you may be getting an unwanted carriage return as part of your filetocheck buffer.

How can I clear the contents of a file

I would like to know how the contents of a file can be cleared in C. I know it can be done using truncate, but I can't find any source clearly describing how.
The other answers explain how to use truncate correctly... but if you found yourself on a non-POSIX system that doesn't have unistd.h, then the easiest thing to do is just open the file for writing and immediately close it:
#include <stdio.h>
int main()
{
FILE *file = fopen("asdf.txt", "w");
if (!file)
{
perror("Could not open file");
}
fclose(file);
return 0;
}
Opening a file with "w" (for write mode) "empties" the file so you can start overwriting it; immediately closing it then results in a 0-length file.
The truncate() call in UNIX is simply:
truncate("/some/path/file", 0);
While you can just open and close the file, the truncate call is designed specifically for this use case:
#include <unistd.h> //for truncate
#include <stdio.h> //for perror
int main()
{
if (truncate("/home/fmark/file.txt", 0) == -1){
perror("Could not truncate")
}
return 0;
}
If you already have the file open, you can use that handle with ftruncate:
#include <stdio.h> //for fopen, perror
#include <unistd.h> //for ftruncate
int main()
{
FILE *file = fopen("asdf.txt", "r+");
if (file == NULL) {
perror("could not open file");
}
//do something with the contents of file
if (ftruncate(file, 0) == -1){
perror("Could not truncate")
}
fclose(file);
return 0;
}
truncate(2) is not a portable call. It only conforms to 4.2BSD. While it is found on most *nix type systems, I would say use a POSIX.1 compliant routines which are pretty much guaranteed on most modern environments (including Windows).
so here is a POSIX.1-2000 compliant code snippet:
int truncate_file(const char *name) {
int fd;
fd = open (name, O_TRUNC|O_WRONLY);
if ( fd >= 0 )
close(fd); /* open can return 0 as a valid descriptor */
return fd;
}
For deleting the contents of a fie obviously there is basic method of opening a file in write mode "w" and then close it without doing any changes in it.
FILE *fp = fopen (file_path, "w");
fclose(fp);
this will delete all the data in file as when you open a already existing file using "w" mode the file is deleted and a new file with the same name is opened for writing, this will result into deletion of contents of your file.
BUT there is truncate syscall in UNIX systems, which is specially for the same purpose and pretty easy to use:
truncate (filepath, 0);
if you have already opened your file so either you close your file before doing truncate or use ftruncate
ftruncate (file_path, 0);

Resources