Thread: filei/o

  1. #1
    Registered User
    Join Date
    Sep 2001
    Posts
    6

    filei/o

    HEY there
    I need to write a program that reads the autoexec.bat file
    and if it reads blaster it must return a message reading thanks
    here is my code but it's not working please help and thanks for all
    the previous help

    #include<stdio.h>
    void main ()
    {
    int i;
    char read[20];
    FILE *ptr;
    ptr = fopen ("\\Autoexec.bat","a+");
    if(read[i] == "BLASTER")
    fprintf(stdout,"Thanks");
    i = fscanf(ptr," %s",&read);
    for( ;i !=EOF; )
    {
    i = fscanf(ptr," %s",&read);
    fprintf(stdout," %s",read);
    }
    getchar();
    }

  2. #2
    Registered User
    Join Date
    Aug 2001
    Posts
    247
    Hi since there is no intialisation of your char array...which you have declared as either an array of chars [20] elements or a char string of [20] characters.

    if you intend
    char read[20]; to be a string then read[i] would access the first element of the string.....a single character...in the case of 'BLASTER' this would be 'B' while i = 0. Your compiler should not allow you to do this (read[i] =="BLASTER") **MAKES POINTER OUT OF INTEGER"** or a similar error message.

    what I guess you want is an array of strings..therefore...
    char read [20][20]; /*20 strings of 20 characters*/

    thereafter for the expression
    if (read[i] =="BLASTER") IS ILLEGAL
    guess you'd need
    if(!strcmp(read[i], "BLASTER") /*your code*/

    even then you must place values into the string prior to this expression. I guess you want to read file prior to this
    fgets(ptr, read[i]); /*doing this blind, no books*/
    /*might not be correct syntax here*/
    Last edited by bigtamscot; 10-02-2001 at 05:40 AM.
    hoping to be certified (programming in c)
    here's the news - I'm officially certified.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Like so
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main ( ) {
        char buff[BUFSIZ];
        FILE *fp = fopen( "c:\\autoexec.bat", "r" );
        while ( fgets( buff, BUFSIZ, fp ) != NULL ) {
            if ( strstr( buff, "BLASTER") != NULL ) {
                fputs( buff, stdout );
            }
        }
        fclose( fp );
        return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    what happens if BLASTER starts at the BUFSIZ-2 'th character and there are no newlines in the first BUFSIZ-1 characters ?

    Originally posted by Salem
    Like so
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main ( ) {
        char buff[BUFSIZ];
        FILE *fp = fopen( "c:\\autoexec.bat", "r" );
        while ( fgets( buff, BUFSIZ, fp ) != NULL ) {
            if ( strstr( buff, "BLASTER") != NULL ) {
                fputs( buff, stdout );
            }
        }
        fclose( fp );
        return 0;
    }

  5. #5
    Unregistered
    Guest
    > what happens if BLASTER starts at the BUFSIZ-2 'th character
    > and there are no newlines in the first BUFSIZ-1 characters ?

    Error checking, and single line checking / valid "BLASTER" line checking, was not a requirement of the program. The original poster's only requirement was that if it found the text "BLASTER", then it displayed a message.

    However, I believe what you're asking is: What if your buffer read goes something like this:

    BLAS[end of first read]TER...

    This will never happen. Ok, it could, but it's very unlikely. Usually the autoexec.bat file is very small. Thus, if you read 4096 bytes, you've pretty much covered all your bases. However, sinc it is possible:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main ( void ) {
    
        FILE *fp = fopen( "c:\\autoexec.bat", "r" );
        int c=0,match=0;
    
        while( (c = fgetc( fp )) != EOF )
        {
            if ( c == 'B' ) { c=fgetc(fp);
            if ( c == 'L' ) { c=fgetc(fp);
            if ( c == 'A' ) { c=fgetc(fp);
            if ( c == 'S' ) { c=fgetc(fp);
            if ( c == 'T' ) { c=fgetc(fp);
            if ( c == 'E' ) { c=fgetc(fp);
            if ( c == 'R' ) { match = 1; break; }
            }}}}}} //lazy indenting today. fix it yourself
        }
        fclose( fp );
        if ( match )
            puts("Match found.");
        else
            puts("No match found.");
        return 0;
    }
    There. That'll work. No buffer needed.

    Quzah.

  6. #6
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    making spurious assumtions about the size of autoexec.bat doesnt help , my point was very clear if BLASTER starts in the BUFSIZ-2'th position and there are no newlines before that only portions of the string BLASTER will be read in the buffer , so at least one occurence of BLASTER will not be found , and hence not printed .
    Originally posted by Unregistered
    > what happens if BLASTER starts at the BUFSIZ-2 'th character
    > and there are no newlines in the first BUFSIZ-1 characters ?

    Error checking, and single line checking / valid "BLASTER" line checking, was not a requirement of the program. The original poster's only requirement was that if it found the text "BLASTER", then it displayed a message.

    However, I believe what you're asking is: What if your buffer read goes something like this:

    BLAS[end of first read]TER...

    This will never happen. Ok, it could, but it's very unlikely. Usually the autoexec.bat file is very small. Thus, if you read 4096 bytes, you've pretty much covered all your bases. However, sinc it is possible:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main ( void ) {
    
        FILE *fp = fopen( "c:\\autoexec.bat", "r" );
        int c=0,match=0;
    
        while( (c = fgetc( fp )) != EOF )
        {
            if ( c == 'B' ) { c=fgetc(fp);
            if ( c == 'L' ) { c=fgetc(fp);
            if ( c == 'A' ) { c=fgetc(fp);
            if ( c == 'S' ) { c=fgetc(fp);
            if ( c == 'T' ) { c=fgetc(fp);
            if ( c == 'E' ) { c=fgetc(fp);
            if ( c == 'R' ) { match = 1; break; }
            }}}}}} //lazy indenting today. fix it yourself
        }
        fclose( fp );
        if ( match )
            puts("Match found.");
        else
            puts("No match found.");
        return 0;
    }
    There. That'll work. No buffer needed.

    Quzah.

  7. #7
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284

    Post

    there is a little problem with your code if there is a B just before BLASTER
    for eg. if a autoexec.bat consists of the following characters
    set t=BBLASTER
    your code will not detect BLASTER
    you will have to use ungetc to extract the pattern
    I have slightly modified your code , I think this should work , there might be some bugs , please let me know , Sedgewick's book has some real neat algorithms on pattern searching but the good ones are so darn complicated .
    /*****warning code dump starts*/

    #include <stdio.h>

    int main(void)
    {
    int c;
    FILE *fp;
    if( (fp=fopen("autoexec.bat","r")) == NULL)
    {
    printf("unable to open autoexec.bat");
    return 1;
    }

    while( (c=fgetc(fp)) !=EOF)
    {

    if( c=='B')
    {
    c=fgetc(fp);
    if( c != 'L')
    {
    if(c==EOF) break;
    else
    {
    ungetc(c,fp);
    continue;
    }
    }
    /*found BL */
    c=fgetc(fp);
    if(c != 'A')
    {
    if(c==EOF) break;
    else
    {
    ungetc(c,fp);
    continue;
    }
    }
    /*found BLA*/
    c=fgetc(fp);
    if(c != 'S')
    {
    if(c==EOF) break;
    else
    {
    ungetc(c,fp);
    continue;
    }
    }
    /*found BLAS*/
    c=fgetc(fp);
    if(c != 'T')
    {
    if(c==EOF) break;
    else
    {
    ungetc(c,fp);
    continue;
    }
    }
    /*found BLAST*/
    c=fgetc(fp);
    if(c != 'E')
    {
    if(c==EOF) break;
    else
    {
    ungetc(c,fp);
    continue;
    }
    }
    /*found BLASTE*/
    c=fgetc(fp);
    if(c != 'R')
    {
    if(c==EOF) break;
    else
    {
    ungetc(c,fp);
    continue;
    }
    }
    /*an instance of BLASTER found print it*/
    printf("BLASTER ");
    }
    }
    return 0;
    }


    Originally posted by pinko_liberal
    making spurious assumtions about the size of autoexec.bat doesnt help , my point was very clear if BLASTER starts in the BUFSIZ-2'th position and there are no newlines before that only portions of the string BLASTER will be read in the buffer , so at least one occurence of BLASTER will not be found , and hence not printed .

  8. #8
    Unregistered
    Guest
    pinko_liberal, your example does exactly the same thing as mine, except it takes longer and is less efficient.

    There is no need to keep checking EOF here, additionally, there is no need to run through the loop the way you do. It just isn't needed.

    My method is the most efficient way to solve this problem with the given specifications the original poster provided. They did not speficy they were looking for the full SET BLASTER line. If so, you would have to check for:

    SET BLASTER=....

    As such, my method is the safest as far as word fragmentation goes. It also avoids the unnecessary looping and 'ungetc'. The only change needed, is the end result of where I put the EOF check.

    There is no need to check for EOF after every single read. It is done for you:

    if( c == 'B' ) read into c, then if( c == 'L' ) read into c, ...

    If, after reading a 'B', the next character is EOF, it will not equal 'L', and as such, the read will stop, and the loop EOF check will happen.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main ( void ) {
    
        FILE *fp = fopen( "c:\\autoexec.bat", "r" );
        int c=0,match=0;
    
        do
        {
            c = fgetc( fp );
    
            if ( c == 'B' ) { c=fgetc(fp);
              if ( c == 'L' ) { c=fgetc(fp);
                if ( c == 'A' ) { c=fgetc(fp);
                  if ( c == 'S' ) { c=fgetc(fp);
                    if ( c == 'T' ) { c=fgetc(fp);
                      if ( c == 'E' ) { c=fgetc(fp);
                        if ( c == 'R' ) { match = 1; break;
                        }
                      }
                    }
                  }
                }
              }
            }
        } while( c != EOF );
        fclose( fp );
        if ( match )
            puts("Match found.");
        else
            puts("No match found.");
        return 0;
    }
    Again, if at any point, EOF is encountered, this loop will stop reading. There is no need to ungetc / continue as you are doing.

    Quzah.

  9. #9
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    No sir your your earlier program does not work if there is a B just before BLASTER
    try out your earlier code on an autoexec.bat consisting of a single line
    set b=BBLASTER
    nowhere did the first poster say that detect those BLASTER's which were preceded and followed by a white space .
    there is an occurence of BLASTER and it is not detected .

    the output:
    No match found.

    So , your earlier program is simply incorrect , it may work sometimes , and sometimes it will fail .
    In fact it will fail to detect BLASTER if it is a part of string such as
    BLBLASTER,BLABLASTER . i.e., whenever BLASTER is preceded by a proper substring of itself .

  10. #10
    Unregistered
    Guest
    The only reason it didn't work was because I used a while() loop instead of a do-while() loop. It could fail if there was a partial because of an additional c=fgetc(fp) line before the check. The switch to a do-while resolved the error. It is still more efficient than using ungetc.

    Quzah.

  11. #11
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    I am sorry your do{ }while(..); program also failed the
    set b=BBLASTER test , your program when it chews thru the characters stops when it has chewed one more than neccessary and it doesnt put it back ,
    eg., in BBLASTER , it looks at B , reads the next one it is also B
    so it stops , it moves on to L , it doesnt take take into account that a occurence of BLASTER could have been started by it.

    Originally posted by Unregistered
    The only reason it didn't work was because I used a while() loop instead of a do-while() loop. It could fail if there was a partial because of an additional c=fgetc(fp) line before the check. The switch to a do-while resolved the error. It is still more efficient than using ungetc.
    Quzah.

  12. #12
    Unregistered
    Guest
    Hm. Nifty. You're right. I suppose it would have helped if I hadn't been posting from work (not compiling it). Just going from how I thought it'd work.

    Quzah.

  13. #13
    Unregistered
    Guest
    er... posting from word == not compiling (I really should sign in one of these times instead of just going unregistered. Oh well.)

    Quzah.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with FileI/O and Linked lists.
    By Red Army in forum C++ Programming
    Replies: 1
    Last Post: 05-27-2002, 03:30 PM