Problem moving data between 'txt' files using: fopen, fscanf & fgets.

This is a discussion on Problem moving data between 'txt' files using: fopen, fscanf & fgets. within the C Programming forums, part of the General Programming Boards category; Hi. I'm noob to this programming business and as part of a self-inflicted learning exercise, I've been trying to write ...

  1. #1
    Registered User Baaaah!'s Avatar
    Join Date
    Oct 2005
    Location
    UK
    Posts
    23

    Problem moving data between 'txt' files using: fopen, fscanf & fgets.

    Hi. I'm noob to this programming business and as part of a self-inflicted learning exercise, I've been trying to write a programme that functions as follows:

    - read a string (single word) from existing text file(1).
    - output read string to new file(2).
    - copy string to new char variable.
    - output copied string to another new file(3).
    - read string from file3 and output to another new file(4).

    I don't get any errors when I compile, but when I run the program it crashes. It manages to create the new 'txt' files, but doesn't write anything to them. . I've run out of things to try I'm afraid. As far as I can tell it's not happy about performing the 'fscanf' function again - though frankly it could be anything that's breaking it as my knowledge is somewhat limited.

    Any ideas regarding what I'm doing wrong, or missing would be welcome .

    Code:
                    /* Trying to write a program to move strings */
                    /* between separate 'txt' files.             */
                    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    FILE *fp1, *fp2, *fp3, *fp4;
    
    char oneword2[100];
    
    char read_file(void);
    
    int main()
    {
        char oneword1[100], transfer[100];
        
        fp1 = fopen("stuff1.txt", "r");   /* '.txt' file with one line of text */
        fp2 = fopen("stuff2.txt", "w+");
        fp3 = fopen("stuff3.txt", "w+");
        fp4 = fopen("stuff4.txt", "w+");
        
           printf("23\n");
        /* Read stuff1.txt, place data in stuff2.txt */ 
        fscanf(fp1, "%s", oneword1);
        fputs(oneword1, fp2);
        
           printf("27\n");
        /* Copy data to 'transfer', place data in stuff3.txt */
        strcpy(transfer, oneword1);
        fputs(transfer, fp3);
           printf("30\n");
        
        /* Problem area */
        read_file(); 
           printf("34\n");
        fputs(oneword2, fp4);
           printf("36\n");
        
        /* Close all files */
        fclose(fp1);
        fclose(fp2);
        fclose(fp3);
        fclose(fp4);
        
        return 0;
    }
    
    char read_file(void)
    {
         fscanf(fp3, "%s", oneword2);
         printf("48function\n");
         return((char)oneword2);
    }
    Apologies if I've posted too much here and I wasn't sure if I should remove the printf's which I was using to try and find the breaking point.

    Thanks

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,159
    read_file() is an...odd...function. You read in a string, but then you're returning the string cast as a char. When you use an array's name without a subscript then you're using a pointer to the first element in the array. So let's say char oneword2[100] exists starting at memory address 0x100, then oneword2[5] references memory address 0x105 and gives you the value there. But oneword2 by itself gives you the value 0x100. oneword2[0] would give you the value at memory address 0x100. So oneword2 and &oneword2[0] are the same thing.

    So your read_file() function is trying to squeeze the memory address that oneword2 lives at into an itty bitty 1-byte char and then returns that mangled memory address. You're not even using the return value from read_file() though so I'm not sure why you're doing that anyway.

    There's other problems in the program, but that's a glaring one.

    EDIT: As an aside, consider using the __LINE__ macro provided by your compiler for debugging instead of manually typing in the line numbers: Something like printf("%d\n", __LINE__); will work. That way if you add some code to fix a problem it doesn't screw up all your debugging line numbers below that point.
    Last edited by itsme86; 10-12-2005 at 11:25 AM.
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,788
    A big reason you don't read anything is that your position within the file needs to be reset after the write operation. After the write operation, you are at the end of the file. When you try to read there is nothing to read because of this. You should probably make a call to fseek or rewind prior to attempting to read from that file. Alternately, you could close that third file and then reopen it. Also, you should be mindfull about checking the return values from your fopen function calls.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User Baaaah!'s Avatar
    Join Date
    Oct 2005
    Location
    UK
    Posts
    23
    Thanks for the response guys.

    itsme86: yeah, I think I see what you're saying there. I'm basically trying to cram a very large peg into a very small hole, so to speak. I'm still not 100% clear on how to use arrays correctly in my code efforts - along with just about everything else . I'll have a tinker with that part and see if I can get it working correctly.

    I'm going to have to look at this thing more carefully, as I thought I was actually using the value returned from read_file(). Think I better have another look at functions while I'm at it .

    Thanks for the info on the macro as well, that's likely to come in very handy.

    hk_mp5kpdw: thanks for the info. I'd have never considered that that was happening. I seem to have written a very untidy program, especially in terms of memory. I'll give your suggestions a try.

    Cheers.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Something like printf("%d\n", __LINE__); will work.
    Or better yet . . .
    Code:
    #define debug \
        fprintf(stderr, "(" __FILE__ "::" __func__ "()::%i)\n", __LINE__);
    I think __func__ is C99.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User Baaaah!'s Avatar
    Join Date
    Oct 2005
    Location
    UK
    Posts
    23
    dwks: Thanks, I'll give that a go too.

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,341
    All your fopen and fgets / fscanf calls should have some error trapping on them.
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  8. #8
    Registered User Baaaah!'s Avatar
    Join Date
    Oct 2005
    Location
    UK
    Posts
    23
    Quote Originally Posted by Salem
    All your fopen and fgets / fscanf calls should have some error trapping on them.

    Errrr... ok. You got me there, I don't know how to do that. Is there any info on this I can read. Cheers.

  9. #9
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,788
    Error trapping for fopen calls involves simply checking if the file pointer is NULL after the open call and dealing with that condition in an appropriate manner, i.e. outputting an error message and exiting the program or asking the user to type in a new filename and try again as an example.

    Code:
    FILE* fp1;
    
    ...
    
    fp1 = fopen("doc.txt","r");
    if( fp1 == NULL )
    {
        printf("Error: Could not open doc.txt\n");
        exit(1);
    }
    else
    {
        printf("Success:  Opened input file doc.txt\n");
    }
    Error trapping for fgets involves the same thing, if the function returns NULL, then there was either an error reading from the file or we are at the end of the file and there is no more stuff to read.

    Code:
    char buffer[100];
    if( fgets(buffer,sizeof(buffer),fp1) == NULL )
    {
        printf("Error or End-of-file reading from doc.txt\n");
    }
    else
    {
        /* Do stuff with the data we just read */
    }
    Error trapping for fscanf involves testing the number of values successfully scanned/parsed from the file against what you expect to find (the value EOF is returned if an error or end-of-file was encountered).

    Code:
    int value1, value2;
    char name[30];
    int return;
    /* Try to read in 3 items from the file */
    return = fscanf(fp1,"%d %s %d",&value1,name,&value2);
    if( return == EOF )
    {
        printf("Error or End-of-file reached reading from doc.txt\n");
        /* Do something else perhaps? */
    }
    else if( return != 3 )
    {
        printf("Error:  Could not read all three values from doc.txt\n");
        /* Do something else perhaps? */
    }
    else
    {
        printf("Success reading three values from doc.txt\n");
        /* Do stuff with data we just read */
    }
    This is just a basic framework of what you might do.
    Last edited by hk_mp5kpdw; 10-13-2005 at 07:57 AM. Reason: Forgot semicolon after fscanf call
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  10. #10
    Registered User Baaaah!'s Avatar
    Join Date
    Oct 2005
    Location
    UK
    Posts
    23
    hk_mp5kpdw: wow thanks. I see what your saying. It'll give me more feedback on what's occurring, or not occurring, in the program - assuming I implement it correctly of course. I'm going to have a go at re-writing the prog. Hopefully I'll be able to do all this cool advice a degree of justice........

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Code:
    int return;
    That's not a valid variable name - it's a C keyword.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,788
    Quote Originally Posted by dwks
    Code:
    int return;
    That's not a valid variable name - it's a C keyword.
    Oops!
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  13. #13
    Registered User Baaaah!'s Avatar
    Join Date
    Oct 2005
    Location
    UK
    Posts
    23
    Well, finally got around to trying to correct the problems with this program and I think I've got it working roughly the way that I wanted it to. I've tried to keep things as simple as possible in this version, focusing purely on the main function rather than trying to include user input and such.

    One thing I haven't included is the error trapping mentioned and outlined by hk_mp5kpdw. This was simply to keep the size of the posted code to a minimum, I haven't ignored your advice . Closing the written file and then opeing it again seems to have sorted quite a few of the problems, so thanks again for the info on that.

    Any further advice appreciated on my noob efforts

    Code:
                /* Reading and moving strings between 'txt' files */
                
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    FILE *fp1, *fp2;
    
    int main()
    {
        char sentence1[200], oneword[50], inputword[50], c, *z;
        
        /* Define input word */
        strcpy(inputword, "line");
        
        /* Open existing text file and read one sentence */
        fp1 = fopen("stuff1.txt", "r");
        do
        {
        z = fgets(sentence1, 200, fp1);
        
        /* Open new text file and print data into it */
        fp2 = fopen("stuff2.txt", "w");
        fprintf(fp2, "%s", sentence1);
        fclose(fp2); /* Close file to reset read position to start of text line */
        
        /* Re-open file and scan sentence for input word */
        fp2 = fopen("stuff2.txt", "r");
           
           do
           {
              c = fscanf(fp2, "%s", &oneword);
              printf("%d\n", __LINE__);
           
              if(strcmp(oneword, inputword) == 0)
              {
                 printf("%d\n", __LINE__);
                 printf("'%s' found in sentence.\n", inputword);
              }
           }while(c != EOF);
        }while(z != NULL);
        
        fclose(fp1);
        fclose(fp2);
        
        /* exit */
        printf("\n");
        printf("Press 'q':");
        c = _getch();
        
        if(c == 'q')
        {
        return 0;
        }
    }
    Thnks again for the help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. xor linked list
    By adramalech in forum C Programming
    Replies: 23
    Last Post: 10-14-2008, 10:13 AM
  2. problem with data in allocated memory
    By supi in forum C Programming
    Replies: 3
    Last Post: 06-09-2008, 02:06 AM
  3. HELP with storing serial port data into txt file
    By inmaterichard in forum C Programming
    Replies: 2
    Last Post: 04-02-2008, 02:20 AM
  4. data read problem
    By Supra in forum C Programming
    Replies: 0
    Last Post: 02-03-2002, 06:02 PM
  5. Problem when data is printed.
    By Fuzzyman81 in forum C Programming
    Replies: 4
    Last Post: 11-06-2001, 02:24 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21