Thread: Random access files and structures

  1. #1
    I am Diamond Dave
    Join Date
    Mar 2006
    Location
    You'll get some leg tonight for SURE!
    Posts
    34

    Random access files and structures

    Right now I'm trying to read in a buncho f data from the text file "Top_Movies.txt" and putting the data into a structure. This is what I have so far. Now I know it isn't goign to work so I'm not even going to bother trying to compile it...but am I even close? I think I am but what do I know? I've also included the text file, which I do not know how to include in the actual program:

    Code:
    #include <stdio.h>
    
    
    struct Movies {
    	int rank;
    	float rating;
    	char title[25];
    	char director[25];
    };
    
    int main()
    {
    	struct Movies list[50];
    	int ranking;
    	float rate;
    	char movie[25];
    	char bywhom[25];
    	int i;
    	
    	
    	FILE *myFile;
    
    	myFile = fopen("Top_Movies.txt", "r");
    		if (myFile == NULL) {
    			printf("Unable to open Top_Movies.txt.\n");
    		
    		else
    		{ for (i=0;i<50;i++)
    			{
    				fscanf( myFile, "%d%.1f%c%c", &ranking, &rate, movie, bywhom);
    				
    				list[i].rank = ranking;
    				list[i].rating = rate;
    				list[i].title = movie;
    				list[i].director = bywhom;
    		}
    		} 
    		
    		fclose(myFile);
    		return 0;
    
    
    		}
    here's the txt file:

    1, 9.1, The_Godfather, 1972, Francis_Ford_Coppola
    2, 9, The_Shawshank_Redemption, 1994, Frank_Darabont
    3, 8.9, The_Godfather:_Part_II, 1974, Francis_Ford_Coppola
    4, 8.8, The_Lord_of_the_Rings:_The_Return_of_the_King_, 2003, Peter_Jackson
    5, 8.8, Shichinin_no_samurai, 1954, Akira_Kurosawa
    6, 8.8, Schindler's_List, 1993, Steven_Spielberg
    7, 8.7, Casablanca, 1942, Michael_Curtiz
    8, 8.7, Star_Wars:_Episode_V_-_The_Empire_Strikes_Back, 1980, Irvin_Kershner
    9, 8.7, Pulp_Fiction, 1994, Quentin_Tarantino
    10, 8.7, Star_Wars, 1977, George_Lucas
    11, 8.7, Il_Buono_il_brutto_il_cattivo, 1966, Sergio_Leone
    12, 8.7, One_Flew_Over_the_Cuckoo's_Nest, 1975, Milos_Forman
    13, 8.7, The_Lord_of_the_Rings:_The_Fellowship_of_the_Ring, 2001, Peter_Jackson
    14, 8.7, Rear_Window, 1954, Alfred_Hitchcock
    15, 8.6, Cidade_de_Deus, 2002, Fernando_Meirelles
    16, 8.6, The_Usual_Suspects, 1995, Bryan_Singer
    17, 8.6, The_Lord_of_the_Rings:_The_Two_Towers, 2002, Peter_Jackson
    18, 8.6, Raiders_of_the_Lost_Ark, 1981, Steven_Spielberg
    19, 8.6, 12_Angry_Men, 1957, Sidney_Lumet
    20, 8.6, Dr._Strangelove_or:_How_I_Learned_to_Stop_Worrying _and_Love_the_Bomb, 1964, Stanley_Kubrick
    21, 8.6, Citizen_Kane, 1941, Orson_Welles
    22, 8.6, Memento, 2000, Christopher_Nolan
    23, 8.6, Psycho, 1960, Alfred_Hitchcock
    24, 8.6, Goodfellas, 1990, Martin_Scorsese
    25, 8.6, C'era_una_volta_il_West, 1968, Sergio_Leone
    26, 8.5, North_by_Northwest, 1959, Alfred_Hitchcock
    27, 8.5, The_Silence_of_the_Lambs, 1991, Jonathan_Demme
    28, 8.5, Lawrence_of_Arabia, 1962, David_Lean
    29, 8.5, Le_Fabuleux_destin_d'Amelie_Poulain, 2001, Jean-Pierre_Jeunet
    30, 8.5, It's_a_Wonderful_Life, 1946, Frank_Capra
    31, 8.5, Sunset_Blvd., 1950, Billy_Wilder
    32, 8.5, Fight_Club, 1999, David_Fincher
    33, 8.5, American_Beauty, 1999, Sam_Mendes
    34, 8.4, The_Matrix, 1999, Andy_Wachowski/Larry_Wachowski
    35, 8.4, Vertigo, 1958, Alfred_Hitchcock
    36, 8.4, Eternal_Sunshine_of_the_Spotless_Mind, 2004, Michel_Gondry
    37, 8.4, Taxi_Driver, 1976, Martin_Scorsese
    38, 8.4, Apocalypse_Now, 1979, Francis_Ford_Coppola
    39, 8.4, Paths_of_Glory, 1957, Stanley_Kubrick
    40, 8.4, To_Kill_a_Mockingbird, 1962, Robert_Mulligan
    41, 8.4, Der_Untergang, 2004, Oliver_Hirschbiegel
    42, 8.4, Se7en, 1995, David_Fincher
    43, 8.4, The_Pianist, 2002, Roman_Polanski
    44, 8.4, Chinatown, 1974, Roman_Polanski
    45, 8.4, Leon, 1994, Luc_Besson
    46, 8.4, Sen_to_Chihiro_no_kamikakushi, 2001, Hayao_Miyazaki
    47, 8.4, Hotel_Rwanda, 2004, Terry_George
    48, 8.4, American_History_X, 1998, Tony_Kaye
    49, 8.3, The_Third_Man, 1949, Carol_Reed
    50, 8.3, Monty_Python_and_the_Holy_Grail, 1975, Terry_Gilliam/Terry_Jones
    Last edited by DLR; 04-19-2006 at 09:33 PM.

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> if (myFile == NULL)

    if the file pointer is null, be sure not to fclose on it.

    >> for (i=0;i,50;i++)

    always inspect your code for typos and *do* try to compile it.

    >> fscanf( myFile, "%d%.1f%c%c", &ranking, &rate, movie, bywhom);

    %c is for single characters, you'll want %s to get a string. you'll also need to skip all that punctuation, fscanf has format specifiers for that too but unfortunately, I never use the function so I can't remember the exact format (maybe search the board).

    >> list[i].title = movie;

    you can't assign arrays like that in C - use strcpy, strncpy, or memcpy for that. better yet, pass the struct members directly to fscanf and save yourself some trouble.

    also, you should always check the return value of fscanf.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    I am Diamond Dave
    Join Date
    Mar 2006
    Location
    You'll get some leg tonight for SURE!
    Posts
    34
    Quote Originally Posted by Sebastiani
    >> i

    >> for (i=0;i,50;i++)

    always inspect your code for typos and *do* try to compile it.
    yeah i caught that

  4. #4
    I am Diamond Dave
    Join Date
    Mar 2006
    Location
    You'll get some leg tonight for SURE!
    Posts
    34
    Quote Originally Posted by Sebastiani
    %c is for single characters, you'll want %s to get a string. you'll also need to skip all that punctuation, fscanf has format specifiers for that too but unfortunately, I never use the function so I can't remember the exact format (maybe search the board).
    oh yeah duh

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Actually you can use %c to read multiple characters, as long as you spesify the number of characters to read. The diffirence between %c and %s is that %s stops reading at a null or whitespace character. %c just reads how ever many bytes you tell it to, or 1 if you don't specify.

    The sintax (for reading 12 characters) is:
    scanf("%12c",myCharPointer);

  6. #6
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    1, 9.1, The_Godfather, 1972, Francis_Ford_Coppola
    Code:
    struct Movies {
    	int rank;
    	float rating;
    	char title[25];
                    char year[6];
    	char director[25];
    };
    need to read the year as well from the file and store it in the structure/container

    ssharish2005
    Last edited by ssharish2005; 04-19-2006 at 10:46 PM.

  7. #7
    I am Diamond Dave
    Join Date
    Mar 2006
    Location
    You'll get some leg tonight for SURE!
    Posts
    34
    Quote Originally Posted by ssharish2005
    need to read the year as well from the file and store it in the structure/container

    ssharish2005
    can't I use int year?
    this is what I have so far. I have the printf statement at the bottom just to see if it works (which it doesn't). I can't figure out any way to fix it. I also get a warning "warning C4013: 'strncpy' undefined; assuming extern returning int
    Linking..."


    Code:
    #include <stdio.h>
    
    
    struct Movies {
    	int rank;
    	float rating;
    	char title[25];
    	int year;
    	char director[25];
    };
    
    int main()
    {
    	struct Movies list[50];
    	int ranking;
    	float rate;
    	int theyear;
    	char movie[25];
    	char bywhom[25];
    	int i;
    	
    	
    	FILE *myFile;
    
    	myFile = fopen("Top_Movies.txt", "r");
    		if (myFile == NULL) {
    			printf("Unable to open Top_Movies.txt.\n");
    			return (-1);
    		}
    		while (!feof(myFile)) {
    			for (i=0;i<50;i++)
    			{
    				fscanf( myFile, "%d%.1f%d%s%s", &ranking, &rate, &theyear, movie, bywhom);
    				
    				list[i].rank = ranking;
    				list[i].rating = rate;
    				list[i].year = theyear;
    				
    				strcpy (list[i].title, movie);
    				strcpy (list[i].director, bywhom);
    				
    				printf("%s", list[i].title);
    		
    		} 
    		}
    	
    		return (0);
    
    
    		}
    Last edited by DLR; 04-20-2006 at 07:59 PM.

  8. #8
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    Title never gets set because fscanf fails before it gets to that point.
    Your format string does not match your input.
    1, 9.1, The_Godfather, 1972, Francis_Ford_Coppola
    For example you have to take into account the commas
    (don't use %.1f for input just %f)
    Code:
    fscanf( myFile, "%d,%f,%d,%s,%s", &ranking, &rate, &theyear, movie, bywhom);  //Just an example.
    Also, it looks like it should be
    Code:
    int, float, string, int, string
    That's not what you have.


    You should check that fscanf returned the number of elements you expected, and print an error if it didn't.
    Code:
    if(fscanf(...) != 5) {
      //failed to parse the line
    }
    Finally, because of the parse failure you are getting into an infinite loop. You never get to the end of the file.
    The FAQ has an entry on why it is bad to use feof to control a loop.
    Better to use fgets then parse the line with sscanf.

    example:
    Code:
        char line[80];
    
        //loop through each line in the file
        while (fgets(line, sizeof(line), myFile)) {
            //Things to do...
            //-Make sure sscanf returned the correct count
            //-Fix the format string to match my input
            //-flose my file when done (outside of loop)
            //-Do I need these temporary variables? why not just read into list[i].rank etc.
    
            sscanf( line, "%d,%f%d%s%s", &ranking, &rate, &theyear, movie, bywhom);
    
            list[i].rank = ranking;
            list[i].rating = rate;
            list[i].year = theyear;
    
            strcpy (list[i].title, movie);
            strcpy (list[i].director, bywhom);
            i++;
        }
    Last edited by spydoor; 04-21-2006 at 07:54 AM.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    The FAQ has an entry on why it is bad to use feof to control a loop.
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Create Copies of Files
    By Kanshu in forum C++ Programming
    Replies: 13
    Last Post: 05-09-2009, 07:53 AM
  2. How to create a C project with multiple source files
    By MSF1981 in forum C Programming
    Replies: 5
    Last Post: 03-22-2009, 09:25 AM
  3. header and source files
    By gtriarhos in forum C Programming
    Replies: 3
    Last Post: 10-02-2005, 03:16 AM
  4. structures and files
    By eth0 in forum C++ Programming
    Replies: 9
    Last Post: 01-06-2004, 06:48 PM
  5. Random File Issues
    By johnnyd in forum C Programming
    Replies: 5
    Last Post: 03-28-2002, 01:15 PM