Hello i want to dynamically initialize an array based on a text file, but for some reason im doing it wrong. i get an error at line "malloc" that the "texto" is not being initialized.
char nome[] = "partidas.txt";
f = fopen(nome, "rt");
int size = fsize(f);
char **texto;
**texto = (char)malloc(size);
int i = 0;
while ((fgets(texto[i], sizeof(texto), f) != NULL))
{
printf("%s\n", texto[i++]);
}
//remember to include the right header files
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define READ_LENGTH 1024
char* pFileContents = NULL;
int iContentsIndex = 0;
long int sz = 0;
FILE* pFD = NULL;
int readCount = 0;
int stat = 0;
// note: all errors are printed on stderr, success is printed on stdout
// to find the size of the file:
// You need to seek to the end of the file and then ask for the position:
pFD = fopen( "filename", "rt" );
if( NULL == pFD )
{
perror( "\nfopen file for read: %s", strerror(errno) );
exit(1);
}
stat = fseek(pFD, 0L, SEEK_END);
if( 0 != stat )
{
perror( "\nfseek to end of file: %s", strerror(errno) );
exit(2);
}
sz = ftell(pFD);
// You can then seek back to the beginning
// in preparation for reading the file contents:
stat = fseek(pFD, 0L, SEEK_SET);
if( 0 != stat )
{
perror( "\nfseek to start of file: %s", strerror(errno) );
exit(2);
}
// Now that we have the size of the file we can allocate the needed memory
// this is a potential problem as there is only so much heap memory
// and a file can be most any size:
pFileContents = malloc( sz );
if( NULL == pFileContents )
{
// handle this error and exit
perror( "\nmalloc failed: %s", strerror(errno) );
exit(3);
}
// then you can perform the read loop
// note, the following reads directly into the malloc'd area
while( READ_LENGTH ==
( readCount = fread( pFileContents[iContentsIndex], READ_LENGTH, 1, pFD) )
)
{
iContentsIndex += readCount;
readCount = 0;
}
if( (iContentsIndex+readCount) != sz )
{
perror( "\nfread: end of file or read error", strerror(errno) );
free( pFileContents );
exit(4);
}
printf( "\nfile read successful\n" );
free( pFileContents );
return(0);
Related
I am trying to write multiple structures in a .DAT file. But after writing it, I am not getting correct values of struct 1, while struct 2 is not able to be find by read function.
Please let me know the solution.
static const char fileName[] = "file.dat";
struct abc
{
int variable;
}ptr1;
ptr1.variable = 5;
struct xyz
{
int variable;
}ptr2;
ptr2.variable = 6;
int write_file_testing()
{
FILE *outfile;
outfile = fopen(fileName, "a");
if (outfile == NULL) return -1;
fwrite(&ptr1, sizeof(struct abc), 1, outfile);
fwrite(&ptr2, sizeof(struct xyz), 1, outfile);
fclose(outfile);
return 0;
}
int read_file_testing()
{
FILE *infile;
infile = fopen(fileName, "r");
if (infile == NULL)
{
fprintf(stderr, "\nError opening file\n");
exit(1);
}
while (fread(&ptr1, sizeof(struct abc), 1, infile))
{
printf("Variable = %d\n", ptr1.variable);
}
while (fread(&ptr2, sizeof(struct xyz), 1, infile))
{
printf("Variable = %d\n", ptr2.variable);
}
fclose(infile);
return 0;
}
the following proposed code:
is a minimal complete example
cleanly compiles
performs the desired functionality
properly handles I/O errors
opens the file for output with the "w" mode rather than the "a" mode so starts with a clean file
eliminates the duplicate struct definition and usage
documents why each header file is included
and now, the proposed code:
#include <stdio.h> // fopen(), fclose(), fread(), fwrite(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
void write_file_testing( void );
void read_file_testing( void );
static const char fileName[] = "file.dat";
struct abc
{
int variable;
};
struct abc ptr1[2];
int main( void )
{
write_file_testing();
read_file_testing();
}
void write_file_testing()
{
FILE *outfile;
outfile = fopen(fileName, "w");
if (outfile == NULL)
{
perror( "fopen to write to file.dat failed" );
exit( EXIT_FAILURE );
}
ptr1[0].variable = 5;
ptr1[1].variable = 6;
if( fwrite(&ptr1[0], sizeof(struct abc), 1, outfile) != 1)
{
perror( "fwrite for first instance of struct failed" );
fclose( outfile );
exit( EXIT_FAILURE );
}
if( fwrite(&ptr1[1], sizeof(struct abc), 1, outfile) != 1 )
{
perror( "fwrite for second instance of struct failed" );
fclose( outfile );
exit( EXIT_FAILURE );
}
fclose(outfile);
}
void read_file_testing()
{
FILE *infile;
infile = fopen(fileName, "r");
if (infile == NULL)
{
perror( "fopen to read file.dat failed" );
exit( EXIT_FAILURE );
}
if( fread(&ptr1[0], sizeof(struct abc), 1, infile) == 1 )
{
printf("Variable = %d\n", ptr1[0].variable);
}
if( fread(&ptr1[1], sizeof(struct abc), 1, infile) == 1 )
{
printf("Variable = %d\n", ptr1[1].variable);
}
fclose(infile);
}
a successful run of the program results in:
Variable = 5
Variable = 6
I am writing some C code to process some data in a file, but I just learned that the file is going to be constantly added to (about 1 time/second, maybe faster). So I'm wondering how do I keep reading from the file as its being added to. Then when I get to the end, wait until the next line is added and then process it. Then wait again and then process, and so on and so on. I have something like:
while(1){
fgets(line, sizeof(line), file);
while(line == NULL){
//wait ? then try to read again?
}
//tokenize line and do my stuff here
}
I thought I could maybe use inotify, but I am getting nowhere with that. Does anyone have any advice?
The most efficient way is using inotify, and the direct way is using the read() system call directly.
using inotify
The following code may give you some help, It works well on Debian 7.0, GCC 4.7:
/*This is the sample program to notify us for the file creation and file deletion takes place in “/tmp/test_inotify” file*/
// Modified from: http://www.thegeekstuff.com/2010/04/inotify-c-program-example/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/inotify.h>
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
int main( )
{
int length, i = 0;
int fd;
int wd;
char buffer[EVENT_BUF_LEN];
/*creating the INOTIFY instance*/
fd = inotify_init();
/*checking for error*/
if ( fd < 0 ) {
perror( "inotify_init error" );
}
/* adding the “/tmp/test_inotify” test into watch list. Here,
* the suggestion is to validate the existence of the
* directory before adding into monitoring list.
*/
wd = inotify_add_watch( fd, "/tmp/test_inotify", IN_CREATE | IN_DELETE | IN_ACCESS | IN_MODIFY | IN_OPEN );
/* read to determine the event change happens on “/tmp/test_inotify” file.
* Actually this read blocks until the change event occurs
*/
length = read( fd, buffer, EVENT_BUF_LEN );
/* checking for error */
if ( length < 0 ) {
perror( "read" );
}
/* actually read return the list of change events happens.
* Here, read the change event one by one and process it accordingly.
*/
while ( i < length ) {
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if( event->len == 0) {
// For a single file watching, the event->name is empty, and event->len = 0
printf(" Single file watching event happened\n");
} else if ( event->len ) {
if ( event->mask & IN_CREATE ) {
if ( event->mask & IN_ISDIR ) {
printf( "New directory %s created.\n", event->name );
} else {
printf( "New file %s created.\n", event->name );
}
} else if ( event->mask & IN_DELETE ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s deleted.\n", event->name );
} else {
printf( "File %s deleted.\n", event->name );
}
} else if( event->mask & IN_ACCESS ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s accessed.\n", event->name );
} else {
printf(" File %s accessed. \n", event->name );
}
} else if( event->mask & IN_MODIFY ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s modified.\n", event->name );
} else {
printf(" File %s modified. \n", event->name );
}
} else if( event->mask & IN_OPEN ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s opened.\n", event->name );
} else {
printf(" File %s opened. \n", event->name );
}
} else {
printf( "Directory or File is accessed by other mode\n");
}
}
i += EVENT_SIZE + event->len;
}
/* removing the “/tmp/test_inotify” directory from the watch list. */
inotify_rm_watch( fd, wd );
/* closing the INOTIFY instance */
close( fd );
}
When runing the above program. You could test it by create a file or directoy named /tmp/test_inotify.
A detailed explanation could be found here
Use read system call
If a file is open, and have read to the end of current file size. the read() system call will return 0. And if some writer wrote N bytes to this file later, and then the read() will just return min(N, buffersize).
So it works correctly for your circumstance. Following is an examples of the code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
typedef int FD ;
int main() {
FD filed = open("/tmp/test_inotify", O_RDWR );
char buf[128];
if( !filed ) {
printf("Openfile error\n");
exit(-1);
}
int nbytes;
while(1) {
nbytes = read(filed, buf, 16);
printf("read %d bytes from file.\n", nbytes);
if(nbytes > 0) {
split_buffer_by_newline(buf); // split buffer by new line.
}
sleep(1);
}
return 0;
}
Reference
Thanks to Jonathan Leffler's Comment
http://www.thegeekstuff.com/2010/04/inotify-c-program-example/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main()
{
char ch;
FILE *fp;
long int nbytes_read = 0;
char str [128];
int j = 0;
int first_time = 1;
memset(str, '\0', 128);
fp = fopen("file.txt", "r");
while (1) {
if (first_time != 1) {
fp = fopen("file.txt", "r");
fseek(fp, nbytes_read, SEEK_SET);
sleep(10);
}
if (fp != NULL) {
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n') {
str[j++] = ch;
printf("%s", str);
memset(str, '\0', 128);
j = 0;
} else {
str[j++] = ch;
}
nbytes_read++;
}
//printf("%ld\n", nbytes_read);
first_time = 0;
}
fclose(fp);
}
return 0;
}
You can use select() with the fileno(file) as the file-descriptor. select will return either with a timeout (if you set a timeout) or when you can read from the file.
Using select can be a good choice but if you do not wish to use it, you can add a sleep for a small amount of milliseconds before reading value.
Here are two problems in the program
First, is that when I uncomment the pthread_join() in the main function, there will be a seg fault, other wise the program will run...
Second, is that the output file will be missing the first letter of each word that has stored in the global variable words from last read file. So, for example, there are two files:
one has words "abc abc abc abc abc abc abc abc".
the second has words "def def"
if i input 5 for the second argument when calling a.out, the output in the output file will be
abc
abc
abc
abc
abc
bc
bc
bc
def
def
This is also a werid thing I could not figure out why.
/* main.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <ctype.h>
#include <pthread.h>
#include "hw3.h"
int index_;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct files
{
char *inputfile;
FILE * outputfile;
} files;
void * readFile( void *arg ){
files *info = (files *)arg;
char fileName[80];
strncat(fileName, (info->inputfile), 79);
fileName[80] = '\0';
FILE *outputfd = info->outputfile;
FILE* fd;
fd = fopen(fileName, "r");
if ( fd == NULL) {
fprintf(stderr, "ERROR:<open() failed>\n");
}
printf("TID %d: Opened \"%s\"\n", (unsigned int)pthread_self(), fileName);
fflush(stdout);
int rc;
char ch[1] = {0};
char word[80] = {0};
ch[0] = fgetc(fd);
pthread_mutex_lock(&mutex);
while( ch[0] != EOF){
if( isalnum(ch[0]) ){
// char str = ch[0];
strncat(word, ch, 1);
}
else{//it's a word
if( strlen( word ) >= 2 ){
words[index_] = word;
printf("TID %d: Stored \"%s\" in shared buffer at index [%d]\n",(unsigned int)pthread_self(), word, index_ );
if( index_+ 1 == maxwords ){
index_ = 0;
printf("MAIN: Buffer is full; writing %d words to output file\n", maxwords);
for( unsigned int i = 0; i<maxwords; i++ ){
rc = fwrite( words[i], 1, sizeof(words[i]), outputfd );
fwrite( "\n", 1, sizeof("\n"), outputfd );
if( rc == -1 ){
fprintf(stderr, "ERRPR:<write() failed>\n");
//return EXIT_FAILURE;
}
}
}
else{
index_ ++;
}
}
for(int i = 0; i< strlen(word); i++){
word[i] = '\0';
}
}
ch[0] = fgetc(fd);
}
pthread_mutex_unlock(&mutex);
printf("TID %d: Closed \"%s\"; and exiting\n", (unsigned int)pthread_self(), fileName );
fclose(fd);
pthread_exit( NULL );
}
int main( int argc, char * argv[] ){
if(argc != 4){
fprintf(stderr, "ERROR: Invalid arguments\nUSAGE: ./a.out <input-directory> <buffer-size> <output-file>\n");
return EXIT_FAILURE;
}
//dynamically allocated words buffer with argument 2
maxwords = atoi(argv[2]);
words = (char**)calloc(maxwords, sizeof(char*) );
if ( words == NULL)
{
fprintf( stderr, "ERROR:<word calloc() failed\n>" );
return EXIT_FAILURE;
}
printf("MAIN: Dynamically allocated memory to store %d words\n", maxwords);
fflush(stdout);
//open/create output file of the third argument
FILE* outputfd = fopen (argv[3], "w");
if ( outputfd == NULL )
{
perror( "open() failed" );
return EXIT_FAILURE;
}
DIR * dir = opendir( argv[1] );
if(dir == NULL){
perror("ERRPR:<opendir() failed>");
return EXIT_FAILURE;
}
chdir(argv[1]);
printf("MAIN: Opened \"%s\" directory\n", argv[1]);
fflush(stdout);
pthread_t tid[10];
index_ = 0;
int i = 0;//files index
struct dirent * file;
//files allfiles[20];
char fileName[80];
int rc;
//-----------------------------------------------------------------------
// while loop reads all files in the directory
while ( ( file = readdir( dir ) ) != NULL )
{
struct stat buf;
rc = lstat( file->d_name, &buf ); /* e.g., "xyz.txt" */
/* ==> "assignments/xyz.txt" */
if ( rc == -1 ){
fprintf(stderr, "ERRPR:<lstat() failed>\n");
return EXIT_FAILURE;
}
if ( S_ISREG( buf.st_mode ) )
{
// printf( " -- regular file\n" );
// fflush(stdout);
strncpy(fileName, file->d_name, 79);
files info;
info.inputfile = fileName;
info.outputfile = outputfd;
//printf("%d",i);
printf("MAIN: Created child thread for \"%s\"\n",fileName);
rc = pthread_create( &tid[i], NULL, readFile,(void *)&info );
sleep(1);
i++
}
else if ( S_ISDIR( buf.st_mode ) )
{
// printf( " -- directory\n" );
// fflush(stdout);
}
else
{
// printf( " -- other file\n" );
// fflush(stdout);
}
}
closedir(dir);
printf("MAIN: Closed \"%s\" directory\n", argv[1]);
fflush(stdout);
printf("MAIN: Created \"%s\" output file\n",argv[3]);
fflush(stdout);
//-----------------------------------------------------------------------
for( int j = 0; j<i; j++){
printf( "MAIN: Joined child thread: %u\n", (unsigned int)tid[j] );
pthread_join(tid[i], NULL);
}
for( unsigned int i = 0; i<index_; i++ ){
int rc = fwrite( words[i], 1, sizeof(words[i]), outputfd );
if( rc == -1 ){
fprintf(stderr, "ERRPR:<write() failed>\n");
return EXIT_FAILURE;
}
}
printf( "MAIN: All threads are done; writing %d words to output file\n", index_);
fflush(stdout);
free( words );
fclose( outputfd );
return EXIT_SUCCESS;
}
This here is the whole program, and there is a header file which is just two global variab
char ** words = NULL;
/* global/shared integer specifying the size */
/* of the words array (from argv[2]) */
int maxwords;
Thanks to everyone for the help!
You need separate info objects for each thread. Right now, all of the threads get the same info object, which you change in between creating threads, and therefore, for most of them, by the time they get a chance to look at the name of the file they are supposed to process, it has been changed.
The segmentation fault is being caused by code you have not shown us, so I can't help you with that except to suggest that you apply valgrind.
Here are two more bugs:
char fileName[80];
strncat(fileName, (info->inputfile), 79);
You can only concatenate onto a string, not an unitialized array of characters that may or may not contain a valid string.
char ch[1] = {0};
char word[80] = {0};
ch[0] = fgetc(fd);
pthread_mutex_lock(&mutex);
while( ch[0] != EOF){
The fgets function returns an integer that will be EOF on end of file, otherwise it returns the character value. You convert it to a char and then compare the char to EOF. But that makes no sense since EOF is the integer value that represents end of file. Once cast to a character, it is a valid character that could have been read from the file since the file can contain any characters and "end of file" is not a character.
Im trying to copy a mal file to a text file. So basically I want the contents of the mal file to copy over to the text file. the mal file is name test1.mal and the txt file is name output.txt. This is what I have but it keeps printing out error reading the file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char content[255];
char newcontent[255];
FILE *fp1, *fp2;
fp1 = fopen("test1.mal", "r");
fp2 = fopen("output.txt", "w");
if(fp1 == NULL || fp2 == NULL)
{
printf("error reading file\n");
exit(0);
}
printf("files open correct\n");
while(fgets(content, sizeof (content), fp1) !=NULL)
{
fputs(content, stdout);
strcpy (content, newcontent);
}
printf("%s", newcontent);
printf("text received\n");
while(fgets(content, sizeof(content), fp1) !=NULL)
{
fprintf(fp2, newcontent);
}
printf("file created and text copied");
fclose(fp1);
fclose(fp2);
return 0;
}
The posted code has several problems, many of which are expressed in the comments to the OP's question.
The following code is one way to perform the desired operation.
It cleanly compiles and performs appropriate error checking
Note: the calls to perror() will output, to stderr, the enclosed text and the reason the OS thinks the operation failed.
Note: used open(), close(), read(), write() because there is no guarantee that the input .mal file does not contain embedded NUL characters.
#include <stdio.h> // perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <unistd.h> // read(), write(), close()
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> // open()
// declare the size of the buffers with a meaningful name
// do not use 'magic' numbers
#define BUFF_SIZE 255
int main(void)
{
char content[ BUFF_SIZE ];
int fin;
int fout;
if( 0 > (fin = open("test1.mal", O_RDONLY) ) )
{
perror( "open for read of test1.mal failed" );
exit( EXIT_FAILURE );
}
// implied else, open successful
if( 0 > (fout = open("output.txt", O_WRONLY) ) )
{
perror( "open for write of output.txt failed");
close( fin );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
printf("files open correct\n");
ssize_t readCount;
while( 0 < (readCount = read( fin, content, sizeof( content) ) ) )
{
//fputs(content, stdout); // are you sure the file contents are printable?
if( readCount != write( fout, content, (size_t)readCount ) )
{ // then write error occured
perror( "write of data to output file failed" );
close( fin );
close( fout );
exit( EXIT_FAILURE );
}
// implied else, write successful
}
if( 0 > readCount )
{ // then read error occurred
perror( "read of file failed" );
close( fin );
close( fout );
exit( EXIT_FAILURE );
}
// implied else, complete file copied
printf("file created and text copied\n");
close( fin );
close( fout );
return 0;
} // end function: main
I am writing some C code to process some data in a file, but I just learned that the file is going to be constantly added to (about 1 time/second, maybe faster). So I'm wondering how do I keep reading from the file as its being added to. Then when I get to the end, wait until the next line is added and then process it. Then wait again and then process, and so on and so on. I have something like:
while(1){
fgets(line, sizeof(line), file);
while(line == NULL){
//wait ? then try to read again?
}
//tokenize line and do my stuff here
}
I thought I could maybe use inotify, but I am getting nowhere with that. Does anyone have any advice?
The most efficient way is using inotify, and the direct way is using the read() system call directly.
using inotify
The following code may give you some help, It works well on Debian 7.0, GCC 4.7:
/*This is the sample program to notify us for the file creation and file deletion takes place in “/tmp/test_inotify” file*/
// Modified from: http://www.thegeekstuff.com/2010/04/inotify-c-program-example/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/inotify.h>
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
int main( )
{
int length, i = 0;
int fd;
int wd;
char buffer[EVENT_BUF_LEN];
/*creating the INOTIFY instance*/
fd = inotify_init();
/*checking for error*/
if ( fd < 0 ) {
perror( "inotify_init error" );
}
/* adding the “/tmp/test_inotify” test into watch list. Here,
* the suggestion is to validate the existence of the
* directory before adding into monitoring list.
*/
wd = inotify_add_watch( fd, "/tmp/test_inotify", IN_CREATE | IN_DELETE | IN_ACCESS | IN_MODIFY | IN_OPEN );
/* read to determine the event change happens on “/tmp/test_inotify” file.
* Actually this read blocks until the change event occurs
*/
length = read( fd, buffer, EVENT_BUF_LEN );
/* checking for error */
if ( length < 0 ) {
perror( "read" );
}
/* actually read return the list of change events happens.
* Here, read the change event one by one and process it accordingly.
*/
while ( i < length ) {
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if( event->len == 0) {
// For a single file watching, the event->name is empty, and event->len = 0
printf(" Single file watching event happened\n");
} else if ( event->len ) {
if ( event->mask & IN_CREATE ) {
if ( event->mask & IN_ISDIR ) {
printf( "New directory %s created.\n", event->name );
} else {
printf( "New file %s created.\n", event->name );
}
} else if ( event->mask & IN_DELETE ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s deleted.\n", event->name );
} else {
printf( "File %s deleted.\n", event->name );
}
} else if( event->mask & IN_ACCESS ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s accessed.\n", event->name );
} else {
printf(" File %s accessed. \n", event->name );
}
} else if( event->mask & IN_MODIFY ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s modified.\n", event->name );
} else {
printf(" File %s modified. \n", event->name );
}
} else if( event->mask & IN_OPEN ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s opened.\n", event->name );
} else {
printf(" File %s opened. \n", event->name );
}
} else {
printf( "Directory or File is accessed by other mode\n");
}
}
i += EVENT_SIZE + event->len;
}
/* removing the “/tmp/test_inotify” directory from the watch list. */
inotify_rm_watch( fd, wd );
/* closing the INOTIFY instance */
close( fd );
}
When runing the above program. You could test it by create a file or directoy named /tmp/test_inotify.
A detailed explanation could be found here
Use read system call
If a file is open, and have read to the end of current file size. the read() system call will return 0. And if some writer wrote N bytes to this file later, and then the read() will just return min(N, buffersize).
So it works correctly for your circumstance. Following is an examples of the code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
typedef int FD ;
int main() {
FD filed = open("/tmp/test_inotify", O_RDWR );
char buf[128];
if( !filed ) {
printf("Openfile error\n");
exit(-1);
}
int nbytes;
while(1) {
nbytes = read(filed, buf, 16);
printf("read %d bytes from file.\n", nbytes);
if(nbytes > 0) {
split_buffer_by_newline(buf); // split buffer by new line.
}
sleep(1);
}
return 0;
}
Reference
Thanks to Jonathan Leffler's Comment
http://www.thegeekstuff.com/2010/04/inotify-c-program-example/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main()
{
char ch;
FILE *fp;
long int nbytes_read = 0;
char str [128];
int j = 0;
int first_time = 1;
memset(str, '\0', 128);
fp = fopen("file.txt", "r");
while (1) {
if (first_time != 1) {
fp = fopen("file.txt", "r");
fseek(fp, nbytes_read, SEEK_SET);
sleep(10);
}
if (fp != NULL) {
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n') {
str[j++] = ch;
printf("%s", str);
memset(str, '\0', 128);
j = 0;
} else {
str[j++] = ch;
}
nbytes_read++;
}
//printf("%ld\n", nbytes_read);
first_time = 0;
}
fclose(fp);
}
return 0;
}
You can use select() with the fileno(file) as the file-descriptor. select will return either with a timeout (if you set a timeout) or when you can read from the file.
Using select can be a good choice but if you do not wish to use it, you can add a sleep for a small amount of milliseconds before reading value.