File open method from hardcoded to indexed config file setup?

This is a discussion on File open method from hardcoded to indexed config file setup? within the C Programming forums, part of the General Programming Boards category; I'm writing a small little program using Borland Turbo C++ 3.0 for dos, everything in its current state works fine, ...

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    37

    File open method from hardcoded to indexed config file setup?

    I'm writing a small little program using Borland Turbo C++ 3.0 for dos, everything in its current state works fine, basically I have the program load, and at some point a user can hit L to bring up the SNIP 2 part, where they are brought up with a list of choices, these choices are actual files that are set to open when they pick it. Right now I have 1 to 10(0).

    I load the program, I hit open 1, and it loads my barrens.zon file, draws it to the screen, looks great. I can hit L again to bring up my load screen and pick option 2, it loads the duskwood.zon file, draws it, everything fine.

    Now my question is this, I currently have the program hardcoded with each file I want to use, which atm is about 10, but i'd like add more and not have to modify the program each time. Ultimately I'd like it to read one central index file that I could modify, and have the program then read that file, and put out a menu based on that file, with cases for the switch command, and also load the proper file, I have no idea how to do something like that so figured I'd post and see if anyone had any examples or help they could assist me with.

    Heres some samples of the code I'm using, I know its messy, I haven't "seriously" coded in probably 4-5 yrs and this is just something I'm playing with, can probably tell from the mix of C and C++.

    Code:
    #define MAPFILE   "barrens.zon"
    #define MAPFILE2  "duskwood.zon"
    Code:
    cprintf(" 1 - The Barrens");
    cprintf(" 2 - Duskwood");
    
    choose = getch();
    choose = tolower(choose);
    switch (choose)
    	{
    	   case 'q': break;
    	   case '1': zone =1; read_map(); break;
    	   case '2': zone =2; read_map(); break;
    Code:
    void read_map(void)
    {
    	ifstream gamemap;
    	if(zone == 1)
    	gamemap.open(MAPFILE);
    	else if (zone == 2)
    	gamemap.open(MAPFILE2);
    	else if (zone == 3)
    	gamemap.open(MAPFILE3);
    	else if (zone == 4)
    	gamemap.open(MAPFILE4);
    	else if (zone == 5)
    	gamemap.open(MAPFILE5);
    	else if (zone == 6)
    	gamemap.open(MAPFILE6);
    	else if (zone == 7)
    	gamemap.open(MAPFILE7);
    	else if (zone == 8)
    	gamemap.open(MAPFILE8);
    	else if (zone == 9)
    	gamemap.open(MAPFILE9);
    	else if (zone == 10)
    	gamemap.open(MAPFILE10);
    
    	if(gamemap.fail())
    	{
    	  cerr<<endl<<"***** Error Opening BARRENS.ZON *****"<<endl;
    	  kbhit();
    
    	}
    
    	gamemap.getline(mapfile.zonename,20);
    	gamemap.getline(mapfile.mapline_x1,80);
    	gamemap.getline(mapfile.mapline_x2,80);
    	gamemap.getline(mapfile.mapline_x3,80);
    	gamemap.getline(mapfile.mapline_x4,80);
    	gamemap.getline(mapfile.mapline_x5,80);
    	gamemap.getline(mapfile.mapline_x6,80);
    	gamemap.getline(mapfile.mapline_x7,80);
    	gamemap.getline(mapfile.mapline_x8,80);
    	gamemap.getline(mapfile.mapline_x9,80);
    	gamemap.getline(mapfile.mapline_x10,80);
    	gamemap.getline(mapfile.mapline_x11,80);
    	gamemap.getline(mapfile.mapline_x12,80);
    	gamemap.getline(mapfile.mapline_x13,80);
    	gamemap.getline(mapfile.mapline_x14,80);
    	gamemap.getline(mapfile.mapline_x15,80);
    	gamemap.getline(mapfile.mapline_x16,80);
    	gamemap.getline(mapfile.mapline_x17,80);
    	gamemap.getline(mapfile.mapline_x18,80);
    	gamemap.getline(mapfile.mapline_x19,80);
    	gamemap.getline(mapfile.mapline_x20,80);
    	gamemap.getline(mapfile.mapline_x21,80);
    	gamemap.getline(mapfile.mapline_x22,80);
    	gamemap.getline(mapfile.mapline_x23,80);
    	gamemap.getline(mapfile.mapline_x24,80);
    	gamemap.getline(mapfile.mapline_x25,80);
    	gamemap.close();
    
    	return;
    }

  2. #2
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Just re-read that may need some more explaining, right now I have the 10 choices to load files hardcoded, i'd like the central file lets call it like "global.zon" to be read in by the program each time its run, and say it has 5 entries, it would load up choices 1 through 5, and load those 5 files, but I could go and edit that global file to have more zone files, say 1 through 20 now, when I load the program it would read the global file and dynamically adjust to that file.

    Global.zon would like look this
    ---------------
    barrens.zon
    duskwood.zon
    arathi.zon
    tirisfal.zon

    And then the barrens.zon would have the name , and the graphics I have setup to be pulled in, so I could make it be only one map that loads, or even 50.
    Last edited by Striph; 03-10-2005 at 12:52 PM.

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,169
    I think I would do something like this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define ZONE_INDEX "global.zon"
    
    struct zone
    {
      char *filename;
      char *dispname;
    };
    
    typedef struct zone ZONE;
    
    ZONE *zonelist = NULL;
    int nzones = 0;
    
    void add_zone(char *filename, char *dispname)
    {
      ZONE *z;
    
      if(!(zonelist = realloc(zonelist, sizeof(ZONE) * (nzones + 1))))
      {
        puts("Memory allocation error!");
        exit(EXIT_FAILURE);
      }
    
      z = &zonelist[nzones];
    
      if(!(z->filename = malloc(strlen(filename) + 1)) ||
         !(z->dispname = malloc(strlen(dispname) + 1)))
      {
        puts("Memory allocation error!");
        exit(EXIT_FAILURE);
      }
    
      strcpy(z->filename, filename);
      strcpy(z->dispname, dispname);
      nzones++;
    }
    
    void read_zones(void)
    {
      FILE *fp;
      char buf[1024];
      char *p, *q;
    
      if(!(fp = fopen(ZONE_INDEX, "r")))
      {
        printf("Couldn't open zone index file '%s'\n", ZONE_INDEX);
        exit(EXIT_FAILURE);
      }
    
      while(fgets(buf, sizeof(buf), fp))
      {
        if(!(p = strchr(buf, ':')))
        {
          printf("Line %d: Invalid zone entry!\n", nzones+1);
          exit(EXIT_FAILURE);
        }
    
        *p++ = '\0';
        if((q = strchr(p, '\n')))
          *q = '\0';
    
        add_zone(buf, p);
      }
    
      fclose(fp);
    }
    
    int main(void)
    {
      int i;
    
      read_zones();
    
      puts("Pick a zone:");
      for(i = 0;i < nzones;++i)
        printf("%d - %s\n", i + 1, zonelist[i].dispname);
    
      return EXIT_SUCCESS;
    }
    Then the global.zon file would look like:
    Code:
    itsme@dreams:~/C$ cat global.zon
    barrens.zon:The Barrens
    duskwood.zon:Duskwood
    arathi.zon:The Incredible Arathi
    tirisfal.zon:Lafsirit Backwards
    itsme@dreams:~/C$
    Of course, you don't need to use : as the delimiter. I just arbitrarily picked it as a character that won't show up in the filename or display name.

    And when you run the program you'd get:
    Code:
    itsme@dreams:~/C$ ./zones
    Pick a zone:
    1 - The Barrens
    2 - Duskwood
    3 - The Incredible Arathi
    4 - Lafsirit Backwards
    itsme@dreams:~/C$
    Then the user would choose a number and you'd just have to see if their choice was greater than 0 and less than or equal to nzones. If it was then you just open zonelist[choice - 1].filename

    My example doesn't handle the allocated memory very well, but it was just an example. Normally you'd free all the memory you allocate.

    EDIT: Your program is in C++, but this is the C forum so my example is in C. If you want a C++ option then you might want to post on that forum instead.
    Last edited by itsme86; 03-10-2005 at 02:02 PM.
    If you understand what you're doing, you're not learning anything.

  4. #4
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Nice, some good ideas there, shame it won't compile for me to see how things run, must be something unique to GCC that the ole' borland tc++ compiler doesn't like, getting some convert void * to zone * errors, will have to play around and see what I can get it to do, thanks.

  5. #5
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,169
    Quote Originally Posted by Striph
    getting some convert void * to zone * errors, will have to play around and see what I can get it to do, thanks.
    That's because my example is in C. C++ doesn't like implicit assignments to a different data type. You'll either need to compile it as C or you'll need to C++-ify the code.
    If you understand what you're doing, you're not learning anything.

  6. #6
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Ren global.cpp global.c
    tcc global.c
    global

    1 - The Barrens
    2 - Duskwood
    3 - The Incredible Arathi
    4 - Lafsirit Backwards


    Thanks Itsme86.

    Warning global.c 64: Possibly incorrect assignment in function read_zones

    Thats the if(q = strchr(p, '\n')) line.

    Set it to q == strchr... and changed the printf line at the end to not have the \n, and it works fine too with no errors, do you see any problems with making that change?
    Last edited by Striph; 03-10-2005 at 03:42 PM.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You have it wrong. There is an extra set of parenthesis around that that you're leaving off. And yes, there's a huge difference between:
    Code:
    if( (q = strchr( p, '\n' )) )
    and...
    Code:
    if( q == strchr( p, '\n' ) )
    Quzah.
    Last edited by quzah; 03-10-2005 at 05:05 PM. Reason: Accidential edit, when I meant to quote it.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Hrm, removed the:

    Code:
     if((q = strchr(p, '\n')))
       *q = '\0';
    Lines and it works fine, was that part meant for something? heh

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,169
    Just leave it the way I had it. fgets() stores the \n from the end of the line into the buffer. Those 2 lines of code locate the \n and remove it.
    If you understand what you're doing, you're not learning anything.

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by quzah
    You have it wrong. There is an extra set of parenthesis around that that you're leaving off. And yes, there's a huge difference between:
    Code:
    if( (q = strchr( p, '\n' )) )
    and...
    Code:
    if( q == strchr( p, '\n' ) )
    Nice. I get the following feedback for this post:
    # File open method from h... 03-10-2005 03:17 PM incorrect and unhelpful
    Nice job there Einstein. Not only are you stupid, you don't know your C. If you don't understand the code, then ask a question, or shut the hell up.

    [edit]
    Wait, no, no... let's pretend you think you know what you're talking about. Let's examine the following code to see who is in fact the ignorant one here:

    Code:
    void read_zones(void)
    {
      FILE *fp;
      char buf[1024];
      char *p, *q; /* q is uninitialized */
    
      if(!(fp = fopen(ZONE_INDEX, "r")))
      {
        printf("Couldn't open zone index file '%s'\n", ZONE_INDEX);
        exit(EXIT_FAILURE);
      }
    
      while(fgets(buf, sizeof(buf), fp))
      {
        if(!(p = strchr(buf, ':')))
        {
          printf("Line %d: Invalid zone entry!\n", nzones+1);
          exit(EXIT_FAILURE);
        }
    
        *p++ = '\0';
    
        /*
         * q is first used here
         *
         * Let's do it your way.
         *
         * if((q = strchr(p, '\n')))
         *     *q = '\0';
         */
        if( q == strchr( p, '\n' ) )
            *q = '\0';
    
        /*
         * Now let's examine those two lines of code:
         *
         * "If q equals the return value of
         * strchr, then dereference q and make it contain a null character."
         *
         * But wait! What's this? Where does q point?
         * We don't know! It could point anywhere. What happens if
         * it points some entirely random spot in memory that you don't
         * have access to, you get a segmentation fault if you use it.
         *
         * Now, actually you really luck out here. Because were this a normal
         * event, you'd kill your program. However, in this case, it there's an
         * infinitely small chance this will ever come out to be correct. If it did,
         * it would kill the newline.
         *
         * However, before you start acting like you know what you're talking
         * about, you should learn a bit more about pointers and what happens
         * when you attempt to use them uninitialized. 
         *
         * Furthermore, you should learn the difference between the assignment
         * and equality operators. There is a HUGE difference in those
         * two lines of code. You do that same thing in another program and
         * luck just may not be on your side.
         */
    
        add_zone(buf, p);
      }
    
      fclose(fp);
    }
    Well holy ........, it looks like I WAS right. Who would have imagined!?

    But what do I know?
    [/edit]

    Quzah.
    Last edited by quzah; 03-10-2005 at 05:24 PM. Reason: Clarification, colorization, and commentation!
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    I didn't leave you that feedback, have a moderator check the logs, I appreciate both your assistance though.

  12. #12
    Registered User
    Join Date
    Mar 2005
    Posts
    37
    Also Quzah your right, I don't know anything about pointers, up in the first post I mentioned I haven't coded in 4-5 yrs, and just recently picked things up, so input like the above was what I was looking for.

    Could either of you recommend a good C Pointer book? Thats the one thing I've really never tried to learn, that and things dealing with memory allocation. Thanks!

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Well the post was actually directed at whoever it was that left it, showing that infact I was correct. Be it you or whoever. I really don't care. I was just proving the point.

    As far as pointers go, there's a FAQ entry on the site about them. And another by Prelude. Also there's a half-way decent post on the topic, if I do say so myself. (Actually I've a better one some place around here, but I'm hungry so I'm not going to look any more for it.)

    Quzah.
    Last edited by quzah; 03-10-2005 at 06:50 PM.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Batch file programming
    By year2038bug in forum Tech Board
    Replies: 10
    Last Post: 09-05-2005, 03:30 PM
  2. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 02:58 PM
  3. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 01:58 AM
  4. Invoking MSWord
    By Donn in forum C Programming
    Replies: 21
    Last Post: 09-08-2001, 04:08 PM

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