Thread: Writing to a file checking if the input is new

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    161

    Writing to a file checking if the input is new

    This is a small function that takes a string (a name, an address or a mail) like "Mark" and writes this string in a file IFF there isn't a previous entry for "Mark". I want to write an entry a row.

    The problem is that it seems that fprintf writes also some trash and the function doesn't really work because it tryes to check the presence of "mark" also in the trash that blows up everything.. the code is commented!

    Any idea?

    Code:
    FILE* database;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char * lpCmdLine, int  nCmdShow) { 
      
        database = fopen("database.txt", "a");
        writeDatabase("Mark");
        writeDatabase("Mark");
        writeDatabase("Bob");
        fclose(database);
      
      return 0; 
    }
    Code:
    int writeDatabase(char* mail) {
        char token[MAX_PATH]= "\0";
        char tokentemp[MAX_PATH]= "\0";
        
        printf("string length %d\n", strlen(mail));
        // if the file is empty
        if ((fgets(token, MAX_PATH, database)) == NULL) {
             printf("empty\n");
             // then I will write the first string in the file
             fprintf(database, "%s\n", mail);
             printf("Written at the beginning -> %s\n", mail);
             system("PAUSE");
        } else {  // if the file contains some strings
                  while(fgets(tokentemp, MAX_PATH, database)!= NULL) {
                       printf("Iterating on string %s\n", tokentemp);
                       // analyzing the single token, looking for a previous
                       // entry of the string
                       if (strstr(tokentemp, mail) != NULL) {
                              // previously written
                              printf("Found");
                              system("PAUSE");
                              return 0;
                       }
                  }
                  // otherwise the string is new, then write it
                  fprintf(database, "%s\n", mail);
                  printf("Written -> %s\n", mail);
                  system("PAUSE");
          }
        return 0;
    }
    The output file should contain "mark" and "bob" in 2 different rows.. but it's not the case!!! it is huge, full of trash, like:
    Code:
    Mark
    $=                                                                                                    Mark
    $=
    it is full of spaces (hundreds!) and strange things... ??
    Last edited by BianConiglio; 07-17-2005 at 02:03 PM.
    This forum is the best one I've ever seen. Great ppl, great coders

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > if ((fgets(token, MAX_PATH, database)) == NULL) {
    > fprintf(database, "%s\n", mail);
    There is only one 'file pointer' per file, which means need to be a lot more careful when reading and writing the same file. This typically means you use lots of fseek() and fflush() calls to make sure the file pointer is in the right place, and the file is up to date.

    Also, you normally use this for binary files with fixed-length records, not text files with variable length records.
    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.

  3. #3
    Registered User
    Join Date
    Mar 2004
    Posts
    161
    I've corrected some bugs in my code and it quite works..
    Once I call the function, the file is opened in read mode.. if nothign can be read, I close it, open it again in append mode and write the string. If something is readable, I check if some of the previous entry was the same of the one I have here, if not, I write it, otherwise I trash the string.

    The problem is that It seems to fail at the second cycle because it doesn't check the first written string.. check out the code:

    Code:
    int writeDatabase(char* mail) {
        char startToken[MAX_PATH]= "\0";
        char tokentemp[MAX_PATH]= "\0";
        
        database = fopen("database.txt", "rt");
        printf("Want to write %s\n", mail);
        // if the file is empty
        if ((fgets(startToken, MAX_PATH, database)) == NULL) {
             //printf("empty\n");
             fclose(database); // closing read only
             // then I will write the first string in the file
             database = fopen("database.txt", "at"); // opening append
             fputs(mail,database);
             fputs("\n",database);
             fclose(database); // closing append
             printf("Written at the beginning -> %s\n", mail);
        } else {  // if the file contains some strings
                  while(fgets(tokentemp, MAX_PATH, database)!= NULL) {
                       //printf("Iterating on string %s \n", tokentemp);
                       // analyzing the single token, looking for a previous
                       // entry of the mail
                       if (strstr(tokentemp, mail) != NULL) {
                              // previously written
                              printf("Found\n");
                              fclose(database); // closing read only
                              return 0;
                       }
                  }
                  // otherwise the mail is new, then write it
                  fclose(database); // closing read only
                  database = fopen("database.txt", "at"); // opening append
                  fputs(mail,database);
                  fputs("\n",database);
                  printf("Written -> %s\n", mail);
                  fclose(database); // closing append
          }
        return 0;
    }
    Code:
    FILE* database;
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* lpCmdLine, int nCmdShow) { 
      
        // creating the file
        database = fopen("database.txt", "w");
        fclose(database);
     
        writeDatabase("marco");
        writeDatabase("marco");
        writeDatabase("ciao");
        writeDatabase("ciao");
        writeDatabase("marco");
        writeDatabase("marco");
        writeDatabase("ciao");
        writeDatabase("miao");
        writeDatabase("miao");
        system("PAUSE");
      
      return 0; 
    }
    the debug (printf) output is :
    Want to write marco
    Written at the beginning -> marco
    Want to write marco
    Written -> marco
    Want to write ciao
    Written -> ciao
    Want to write ciao
    Found
    Want to write marco
    Found
    Want to write marco
    Found
    Want to write ciao
    Found
    Want to write miao
    Written -> miao
    Want to write miao
    Found
    As you can seen, the second time I add "marco" it's added without succeding while checking if it was previously entered (it was entered the first time, just before!)

    and the file contains:

    marco
    marco
    ciao
    miao
    as you can see there is a duplicated marco..

    any hints? thanx!
    Last edited by BianConiglio; 07-18-2005 at 03:28 AM.
    This forum is the best one I've ever seen. Great ppl, great coders

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    If the file isn't empty
    > if ((fgets(startToken, MAX_PATH, database)) == NULL) {
    This succeeds.

    And then you read another line (that's 2) with this
    > while(fgets(tokentemp, MAX_PATH, database)!= NULL)

    With text files, the best thing to do is
    - open current file for input
    - open a new file for output
    - while ( fgets() != NULL ) to read each line from the input file
    - use program logic to decide whether to
    = write the line out to the output file
    = write something else to the output file
    = not write anything to the output file

    When you're done, close both files, then delete and rename.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  2. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  3. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM