fgets problems newline

hello,
i'm trying to write a C-program that reads a file line by line.
(and searches each line for a given string)

This file is an special ASCII-database-file, with a lot of entries.
I checked the line with most length, and it was about 4000 characters.

With google i found several pages that said, fgets would get the length of chars given or until the newline character '\n' was found.
Because it didn't work, my first approach was to change the format of the file with the programs dos2unix and unix2dos.
Unfortunately my Code still doesn't work.

I also tried changing my LINE macro (max line length) to all possible values and I don't know what to do anymore. Please Help! :slight_smile:

 

/* lib includes */
/**************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>

/* macro definitions */
/**************************************************************************************************/
#define LINE 4096

/* searchFileLines */
/**************************************************************************************************/
int searchFileLines( const char *filename, const char *searchstring ) {

    FILE *pFile;
    char buffer[LINE];
    int it = 0;

    if( ( pFile = fopen( filename, "r" ) ) == NULL ) {
        fprintf( stderr, "error: could not open file: %s\n", filename );
        return 1;
    }

    while( fgets( buffer, sizeof( buffer ), pFile ) ) {

        it++;
        if( strchr( buffer, '\n' ) == NULL ) {
            fprintf( stderr, "input line too long.\n" );
            //exit( 1 );
        }
        
        printf( "%d: %s\n", it, buffer );
    }

    return 0;
}

/**************************************************************************************************/
int main( const int argc, const char *argv[] ) { 

    /* 1. check filepath */
    /**************************************************************************/
    if( argc != 2 ) {
       printf( "dude, you need to give me a filepath!" );
       return( 1 );
    }

    /* 2. searh File */
    /**************************************************************************/
    if( !searchFileLines( argv[0], "NxNSignOff_ChangeStatusComment" ) )
        fprintf( stderr, "error: could not search file: %s\n", argv[0] );

    return 0;
}


What I mean by it doesn't work:
Allthough the File has about 1400 entries, my code just loops like 23 times and the output given is not readable text that is in the file.

You're using argv[0], which is the name of the executable. For example, if someone at the command typed:

./somedir/someprog --with option

Then argc would be 3, and the following is what the argv array would look like:

argv[0] = "./somedir/someprog"
argv[1] = "--with"
argv[2] = "option"

So you need to use argv[1], or you'll be reading an ELF binary, which will largely be non-printable text.

*D'oh*!
Sorry and Thank You!!

Define 'special database file'. There also lies a problem, I think.

Here is one way to find record lengths in a standard text file:

#include <stdlib.h> // longest text line-- usage: maxrec filename
#include <stdio.h>
#include <sys/stat.h>
size_t filesize(int fd)  // file size in bytes
{
   struct stat st;
   return (fstat(fd, &st)==0)? st.st_size : 0;
}

int max_recsz(char *p, size_t len, FILE* in) // longest record
{
   int mx=0;
   fread(p, 1, len, in);   
   for(len=0; *p; p++, len++)   	
      if(*p=='\n')
      {
        mx=(len>mx)? len: mx;
        len=0;
      }   
   return mx;
}

int main(int argc, char **argv)
{
   FILE *in=fopen((argc<2)? "": argv[1], "r");
   size_t len=(in==NULL)? 0: filesize(fileno(in));
   char *p=(len>0)? calloc(1, len+1): NULL;
   if(p!=NULL)
      printf("%s %d\n", argv[1], max_recsz(p, len, in));
   else
      printf("%s %d: File error, bad file type, empty file\n", 
        (argc>1)? argv[1]: "",0);
   free(p);
   return !len;
}

wow, thx! :slight_smile: great!!

well it isn't really that special i guess. xD
the database file i'm talking about is from the program: "Alienbrain".

Alienbrain (@alienbrain.com):
"Alienbrain is a digital asset management system for artists in the entertainment industry."

Because I couldn't get the SDK working, I decided to do it this way.
(luckily for me all changes are stored in a plain ASCII-file)

i'm not finished yet, but here's the code i've got so far.
(and it is not perfect and not yet minimized)

/* lib includes */
/**************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>

/* macro definitions */
/**************************************************************************************************/
#define LINE 10240
#define MAXY 20480

/* global vars */
/**************************************************************************************************/
char char_lines[MAXY][LINE];
int int_linecount;

/* searchFileLines */
/**************************************************************************************************/
int searchFileLines( const char *filename, const char *searchstring ) {
    
    FILE *pFile;
    char buffer[LINE];
    
    if( ( pFile = fopen( filename, "r" ) ) == NULL ) {
        fprintf( stderr, "error: could not open file: %s\n", filename );
        return 0;
    }
    
    int_linecount = 0;
    while( fgets( buffer, sizeof( buffer ), pFile ) != NULL ) {
        
        if( strchr( buffer, '\n' ) == NULL )
            fprintf( stderr, "input line too long: %d.\n", int_linecount );
        
        if( strstr( buffer, searchstring ) != NULL ) {
            //printf( "%s", buffer );
            strcpy( char_lines[int_linecount], buffer );
        }
        
        int_linecount++;
    }
    
    return 1;
}

/* filterFileLines */
/**************************************************************************************************/
void filterFileLines() {
   //working on it
}

/**************************************************************************************************/
int main( const int argc, const char *argv[] ) { 
    
    /* 1. check filepath */
    /**************************************************************************/
    if( argc != 2 ) {
       printf( "dude, you need to give me a filepath!" );
       return( 1 );
    }
    
    /* 2. search file */
    /**************************************************************************/
    if( !searchFileLines( argv[1], "NxNSignOff_ChangeStatusComment" ) )
        fprintf( stderr, "error: could not search file: %s\n", argv[1] );
    
    return 0;
}

---------- Post updated at 08:00 AM ---------- Previous update was at 12:38 AM ----------

hey,

it's me again. the above code is not really working.
my global array char_lines does not have the entrys that were found in the file
after the function searchFileLines was called.

i'm guessing because buffer does not longer exists after the function was called.

how can i bypass this problem?
by declaring buffer also as a global var?
Or is there a more elegant solution/approach?