Solved

Searching an Array...

Posted on 2000-02-26
33
418 Views
Last Modified: 2010-04-15
I have an array that is collects information about videos:

Title, Type, Actors

I want to add a search feature to it (the search needs to work for title chooses to select on title, ask for the title or piece of a title to search for. For example, if  "wind" is entered as a title fragment, you would list videos with
titles such as: Gone With the Wind, The Black, Winding Road, and         Swindled by Circumstance

Similarly, if an actor is selected, allow a part of an actor’s name to be entered and return all matches for that part.  Would it be possible to make the search case-insensitive?

Here's what I have:

void find(void)
{
      int i;
      char search[];
      
      /* Only loops till hits last video inputted. */
      printf("\n\n"); /* Just to space it out a second! */
      
      printf("\nEnter a video title or actor name. ");
      scanf("%s", &search);
      
      for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
      {
            
            x = strncmp(search, str2,);
            
            printf("Title of movie: %s\n", new_videos[i].title);
            printf("Type of move: %s\n", new_videos[i].type);
            printf("Actors in movie: %s\n\n", new_videos[i].actor);
      }
      Show_Menu(); /*Display Menu to allow for customer input */
}

I can not figure out how to get it to work -

Please help...

Thanks,

maplah
0
Comment
Question by:maplah
  • 19
  • 14
33 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 300 total points
ID: 2561353
Case insensitive search can be done by using 'stricmp()' instead of 'strcmp()'. If you also want to implement a 'substring search', it's better not to actually compare the strings, but using a string search function like 'strstr()', e.g.

#include <ctype.h>

void find(void)
{
int i;
char search[1024];
char title[1024];
char actor[1024];
char* pc;
/* Only loops till hits last video inputted. */
printf("\n\n"); /* Just to space it out a second! */

printf("\nEnter a video title or actor name. ");
scanf("%s", search);

for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
{

/* use a local copy */
strcpy ( title, new_videos[i].title);
strcpy ( actor, new_videos[i].actor);

/* make both search item a string to search lowercase */
pc = search;
while ( pc)
{
  *pc = tolower ( pc);
  pc++;
}

pc = title;
while ( pc)
{
  *pc = tolower ( pc);
  pc++;
}

pc = actor;
while ( pc)
{
  *pc = tolower ( pc);
  pc++;
}

if ( strstr( title, search) || strstr(actor, search))
{
/* found either in actor or title */
printf("Title of movie: %s\n", new_videos[i].title);
printf("Type of move: %s\n", new_videos[i].type);
printf("Actors in movie: %s\n\n", new_videos[i].actor);

}
Show_Menu(); /*Display Menu to allow for customer input */
}

Feel free to ask if you need more information!
0
 

Author Comment

by:maplah
ID: 2561416
JKR,

I am getting these errors when compiling (I am using Visual C++ Version 6.0):

'tolower' : different types for formal and actual parameter 1
 warning C4047: 'function' : 'int ' differs in levels of indirection from 'char *'
warning C4024: 'tolower' : different types for formal and actual parameter 1
warning C4047: 'function' : 'int ' differs in levels of indirection from 'char *'
warning C4024: 'tolower' : different types for formal and actual parameter 1

I am not too sure how to clear these...

Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2561448
Ooops, sorry - you'll have to use

while ( pc)
{
  *pc = (char) tolower ( (int)pc);
  pc++;
}

pc = title;
while ( pc)
{
  *pc = (char) tolower ( (int)pc);
  pc++;
}

pc = actor;
while ( pc)
{
  *pc = (char) tolower ( (int)pc);
  pc++;
}


BTW: These are only warnings, not errors

(Sorry, don't have compilers or docs here, just typed it from scratch...;-)
0
 

Author Comment

by:maplah
ID: 2561454
jkr,

It compiled but when I ran the program and entered some titles/actors/type info and then tried to search - I got the following error:

This program has performed an illegal operation and will be shut down.

Then I click close and it lets me exit out of the program.

Do you have any clues as to why this is happening?

Thanks,

maplah
0
 

Author Comment

by:maplah
ID: 2561458
jkr,

here is the entire code - it may make the previous question easier to answer:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_TITLE 80
#define MAX_TYPE 80
#define MAX_ACTOR 160
#define Max_Value 510
#define CUST_NAME 80
#define CUST_VIDEO 80
#define Max_Cust 510

typedef struct videos_s
{
      char title [ MAX_TITLE ];
      char type  [ MAX_TYPE ];
      char actor [ MAX_ACTOR ];
} video_t;

typedef struct checkout_s
{
      char name [ CUST_NAME ];
      char video  [ CUST_VIDEO ];
} checkout_t;

/*Declare all functions of program! */
void find(void);
void check_out(void);
void return_videos(void);
void find_videos(void);
void add_videos(void);
void print_inventory(void);
void menu_header(void);

/*This function displays the menu! */
void Show_Menu(void);

/*Define Global Variables! */
video_t new_videos[Max_Value];
checkout_t new_checkout[Max_Cust];

int Video_Current=0; /*Initialize current video to 0 */
int Video_Checkout=0; /*Initialize checkout video to 0 */

int main(void)
{
      int menu_val;
      
      Show_Menu(); /*Display Menu first thing! - allow customer input */
      while ((menu_val = getchar()) != '0')  
      {
            getchar();
            switch (menu_val)
            {
                  
            case '1':
                  find();
                  break;
                  
            case '2':
                  check_out();
                  break;
                  
            case '3':
                  return_videos();
                  break;
                  
            case '4':
                  find_videos();
                  break;
                  
            case '5':
                  add_videos();
                  break;
                  
            case '6':
                  print_inventory();
                  break;
                  
            case '7':
                  Show_Menu();
                  break;
                  
            case '8':
                  exit(1);
                  break;
                  
            default:
                  printf("Your selection did not match one of the menu options.\n I do not under stand %d \nPlease enter a valid option. \n", menu_val);
                  break;
            }
            
      }
      
      return(0);
}
/* This option will allow you to search for a video by entering a fragment of a video or title,
type or actors */
void find(void)
{

      int i;
      char search[1024];
      char title[1024];
      char actor[1024];
      char* pc;
      
      /* Only loops till hits last video inputted. */
      printf("\n\n"); /* Just to space it out a second! */
      
      printf("\nSearch for a video title or actor name\nEnter either full or partial info: ");
      scanf("%s", search);
      
      for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
      {
            
            /* use a local copy */
            strcpy ( title, new_videos[i].title);
            strcpy ( actor, new_videos[i].actor);
            
            /* make both search item a string to search lowercase */
            pc = search;
            while ( pc)
            {
                  *pc = (char) tolower ( (int)pc);
                  pc++;
            }
            
            pc = title;
            while ( pc)
            {
                  *pc = (char) tolower ( (int)pc);
                  pc++;
            }
            
            pc = actor;
            while ( pc)
            {
                  *pc = (char) tolower ( (int)pc);
                  pc++;
            }
            
            if ( strstr( title, search) || strstr(actor, search))
            {
                  /* found a match either in actor or title */
                  printf("Title of movie: %s\n", new_videos[i].title);
                  printf("Actors in movie: %s\n\n", new_videos[i].actor);
                  
            }
      Show_Menu(); /* Show display Menu to allow for customer input */       }
}

/* This option lets you check videos out to a customer */
void check_out(void)
{
   int vid;
   int i;
   
   printf("\nEnter how many videos do you want to check out? ");
   scanf("%d", &vid);
   
   for(i = 0; i < vid; i++)
     {
      fflush(stdin);
      printf("\nEnter customer name (Last name, First name): ");
      gets(new_checkout[Video_Checkout].name);
      printf("\nEnter video name: ");
      gets(new_checkout[Video_Checkout].video);
      Video_Checkout++; /* Video_Checkout = Video_Checkout + 1; */
     }
   /* Move on to next customer checkout... */
   Show_Menu(); /*Display Menu to allow for customer input */
}

/* This option allows you to check the videos back in */
void return_videos(void)
{
      int i;
      char cust_name[30];
      
      /* Only loops till hits last video inputted. */
      printf("\n\n"); /* Just to add some space between entries */
      
      printf("\nEnter customer Name (Last name, First name): ");
      gets(cust_name);
      
      for(i = 0; i < Video_Checkout; i++) /* Loop until last video that was entered */
      {
            if (!strcmp(cust_name, new_checkout[i].name))
            {
                  printf("%s is checked back in - Thank You!\n", new_checkout[i].video);
                  /* Clear video from array */
                  strcpy(new_checkout[i].name, "");
                  strcpy(new_checkout[i].video, "");
            }
            else
            {
                  printf("\nThe customer ID Number entered was not found!\nPlease try again.\n");
            }
      }
      Show_Menu(); /*Display Menu to allow for customer input */
}

/* This option allows you to title or actor name, and see a list of videos whose
title or actor list contain the fragment */
void find_videos(void)
{
      char name[30];
      int i;
      
      printf("Enter customer name Last name, First name): ");
      gets(name);
      
      for (i = 0; i < Video_Checkout; i++)
      {
            if (!strcmp(name, new_checkout[i].name))
            {
                  printf("Video: [%s]\n", new_checkout[i].video);
            }
      }
      
      Show_Menu(); /* Display menu to allow for customer input. */
}

/* This option allows you to add videos to the array */
void add_videos(void)
{
      fflush(stdin);
      printf("\nEnter the title of the video?  ");
      gets(new_videos[Video_Current].title);
      printf("\nWhat genre is the video?  ");
      gets(new_videos[Video_Current].type);
      printf("\nEnter up to three actors separated by spaces:  ");
      gets(new_videos[Video_Current].actor);
      Video_Current++; /* Video_Current = Video_Current + 1; */
      /* Move on to next video... */
      Show_Menu(); /* Display menu to allow for customer input */
}

/* This option allows you to print all of the titles in the inventory */
void print_inventory(void)
{
      int i;
      
      /* Only loops till hits last video inputted. */
      printf("\n\n\n"); /* Just to space it out a second! */
      for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
      {
            printf("Title of movie: %s\n", new_videos[i].title);
            printf("Type of move: %s\n", new_videos[i].type);
            printf("Actors in movie: %s\n\n", new_videos[i].actor);
      }
      Show_Menu(); /*Display Menu to allow for customer input */
}

void Show_Menu(void)
{
      printf( "\nSCHLOCKLUSTER VIDEO                       -  MAIN MENU: \n\n");
      printf( "DESCRIPTION/FUNCTION:                        ENTER NUMBER (Then hit enter): \n");
      printf( "Find video(s) (by title, type, or actors) -       1 \n");
      printf( "Check out video(s)                        -       2 \n");
      printf( "Return video(s)                           -       3 \n");
      printf( "Find all videos out to a customer         -       4 \n");
      printf( "Add new video(s)                          -       5 \n");
      printf( "Print inventory list (sorted by...)       -       6 \n");
      printf( "Print Main Menu again                     -       7 \n");
      printf( "To Exit Program Enter 8                   -       8 \n\n");       
}


Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2561523
Have to apologize again, seems to be my fault :-(

while ( pc)

has to read

while ( *pc)

or these loops will run infinetly - sorry...
0
 

Author Comment

by:maplah
ID: 2561533
jkr,

Okay - that fixed that problem but it created another - once the videos are entered - I can run a search and I entered Star Trek and a movie called Starfield  then I did a search for Star and it only returned Starfield - I went to perform another search and the Switch error is kicking in now - I can not enter any menu function with out it throwing up the default error message...

I need to have it return both star movies (for full and partial search) and what's causing the switch statement to go butt whacky?

Thanks,


maplah
0
 

Author Comment

by:maplah
ID: 2561558
jkr,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_TITLE 80
#define MAX_TYPE 80
#define MAX_ACTOR 160
#define Max_Value 510
#define CUST_NAME 80
#define CUST_VIDEO 80
#define Max_Cust 510

typedef struct videos_s
{
      char title [ MAX_TITLE ];
      char type  [ MAX_TYPE ];
      char actor [ MAX_ACTOR ];
} video_t;

typedef struct checkout_s
{
      char name [ CUST_NAME ];
      char video  [ CUST_VIDEO ];
} checkout_t;

/*Declare all functions of program! */
void find(void);
void check_out(void);
void return_videos(void);
void find_videos(void);
void add_videos(void);
void print_inventory(void);
void menu_header(void);

/*This function displays the menu! */
void Show_Menu(void);

/*Define Global Variables! */
video_t new_videos[Max_Value];
checkout_t new_checkout[Max_Cust];

int Video_Current=0; /*Initialize current video to 0 */
int Video_Checkout=0; /*Initialize checkout video to 0 */

int main(void)
{
      int menu_val;
      
      Show_Menu(); /*Display Menu first thing! - allow customer input */
      while ((menu_val = getchar()) != '0')  
      {
            getchar();
            switch (menu_val)
            {
                  
            case '1':
                  find();
                  break;
                  
            case '2':
                  check_out();
                  break;
                  
            case '3':
                  return_videos();
                  break;
                  
            case '4':
                  find_videos();
                  break;
                  
            case '5':
                  add_videos();
                  break;
                  
            case '6':
                  print_inventory();
                  break;
                  
            case '7':
                  Show_Menu();
                  break;
                  
            case '8':
                  exit(1);
                  break;
                  
            default:
                  printf("Your selection did not match one of the menu options.\n I do not under stand %d \nPlease enter a valid option. \n", menu_val);
                  break;
            }
            
      }
      
      return(0);
}
/* This option will allow you to search for a video by entering a fragment of a video or title,
type or actors */
void find(void)
{

      int i;
      char search[1024];
      char title[1024];
      char actor[1024];
      char* pc;
      
      printf("\n\n"); /* Just to space it out a second! */
      
      /* Ask for user input for search function */
      fflush(stdin);      
      printf("\nSearch for a video title or actor name\nEnter either full or partial info: ");
      scanf("%s", search);
      
      for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
      {
            
            /* use a local copy */
            strcpy ( title, new_videos[i].title);
            strcpy ( actor, new_videos[i].actor);
            
            /* make both search items a string to search lowercase */
            pc = search;
            while ( *pc)
            {
                  *pc = (char) tolower ( (int)pc);
                  pc++;
            }
            
            pc = title;
            while ( *pc)
            {
                  *pc = (char) tolower ( (int)pc);
                  pc++;
            }
            
            pc = actor;
            while ( *pc)
            {
                  *pc = (char) tolower ( (int)pc);
                  pc++;
            }
            
            if ( strstr( title, search) || strstr(actor, search))
            {
                  /* found a match either in actor or title */
                  fflush(stdin);
                  printf("Title of movie: %s\n", new_videos[i].title);
                  printf("Actors in movie: %s\n\n", new_videos[i].actor);
            }
                  
            else
            {            
                  printf("No movies or actors matching your description were found!");
            }
      Show_Menu(); /* Show display Menu to allow for customer input */       }
}

/* This option lets you check videos out to a customer */
void check_out(void)
{
   int vid;
   int i;
   
   printf("\nEnter how many videos do you want to check out? ");
   scanf("%d", &vid);
   
   for(i = 0; i < vid; i++)
     {
      fflush(stdin);
      printf("\nEnter customer name (Last name, First name): ");
      gets(new_checkout[Video_Checkout].name);
      printf("\nEnter video name: ");
      gets(new_checkout[Video_Checkout].video);
      Video_Checkout++; /* Video_Checkout = Video_Checkout + 1; */
     }
   /* Move on to next customer checkout... */
   Show_Menu(); /*Display Menu to allow for customer input */
}

/* This option allows you to check the videos back in */
void return_videos(void)
{
      int i;
      char cust_name[30];
      
      /* Only loops till hits last video inputted. */
      printf("\n\n"); /* Just to add some space between entries */
      
      printf("\nEnter customer Name (Last name, First name): ");
      gets(cust_name);
      
      for(i = 0; i < Video_Checkout; i++) /* Loop until last video that was entered */
      {
            if (!strcmp(cust_name, new_checkout[i].name))
            {
                  printf("%s is checked back in - Thank You!\n", new_checkout[i].video);
                  /* Clear video from array */
                  strcpy(new_checkout[i].name, "");
                  strcpy(new_checkout[i].video, "");
            }
            else
            {
                  printf("\nThe customer ID Number entered was not found!\nPlease try again.\n");
            }
      }
      Show_Menu(); /*Display Menu to allow for customer input */
}

/* This option allows you to title or actor name, and see a list of videos whose
title or actor list contain the fragment */
void find_videos(void)
{
      char name[30];
      int i;
      
      printf("Enter customer name Last name, First name): ");
      gets(name);
      
      for (i = 0; i < Video_Checkout; i++)
      {
            if (!strcmp(name, new_checkout[i].name))
            {
                  printf("Video: [%s]\n", new_checkout[i].video);
            }
      }
      
      Show_Menu(); /* Display menu to allow for customer input. */
}

/* This option allows you to add videos to the array */
void add_videos(void)
{
      fflush(stdin);
      printf("\nEnter the title of the video?  ");
      gets(new_videos[Video_Current].title);
      printf("\nWhat genre is the video?  ");
      gets(new_videos[Video_Current].type);
      printf("\nEnter up to three actors separated by spaces:  ");
      gets(new_videos[Video_Current].actor);
      Video_Current++; /* Video_Current = Video_Current + 1; */
      /* Move on to next video... */
      Show_Menu(); /* Display menu to allow for customer input */
}

/* This option allows you to print all of the titles in the inventory */
void print_inventory(void)
{
      int i;
      
      /* Only loops till hits last video inputted. */
      printf("\n\n\n"); /* Just to space it out a second! */
      for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
      {
            printf("Title of movie: %s\n", new_videos[i].title);
            printf("Type of move: %s\n", new_videos[i].type);
            printf("Actors in movie: %s\n\n", new_videos[i].actor);
      }
      Show_Menu(); /*Display Menu to allow for customer input */
}

void Show_Menu(void)
{
      printf( "\nSCHLOCKLUSTER VIDEO                       -  MAIN MENU: \n\n");
      printf( "DESCRIPTION/FUNCTION:                        ENTER NUMBER (Then hit enter): \n");
      printf( "Find video(s) (by title, type, or actors) -       1 \n");
      printf( "Check out video(s)                        -       2 \n");
      printf( "Return video(s)                           -       3 \n");
      printf( "Find all videos out to a customer         -       4 \n");
      printf( "Add new video(s)                          -       5 \n");
      printf( "Print inventory list (sorted by...)       -       6 \n");
      printf( "Print Main Menu again                     -       7 \n");
      printf( "To Exit Program Enter 8                   -       8 \n\n");       
}

It seems that it returns all movies now - no matter what you enter - either full title or partial title - it returns all movies in array.

Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2562485
Sorry for the delay, but I'm living in Europe...

I AM SO DUMB ;-)

The whole function should be

void find(void)
{

int nFound = 0;
int i;
char search[1024];
char title[1024];
char actor[1024];
char* pc;

printf("\n\n"); /* Just to space it out a second! */

/* Ask for user input for search function */
fflush(stdin);
printf("\nSearch for a video title or actor name\nEnter either full or partial info: ");
scanf("%s", search);

for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
{

/* use a local copy */
strcpy ( title, new_videos[i].title);
strcpy ( actor, new_videos[i].actor);

/* make both search items and string to search lowercase */
pc = search;
while ( *pc)
{
*pc = (char) tolower ( (int)*pc);
pc++;
}

pc = title;
while ( *pc)
{
*pc = (char) tolower ( (int)*pc);
pc++;
}

pc = actor;
while ( *pc)
{
*pc = (char) tolower ( (int)*pc);
pc++;
}

if ( strstr( title, search) || strstr(actor, search))
{
/* found a match either in actor or title */
fflush(stdin);
printf("Title of movie: %s\n", new_videos[i].title);
printf("Actors in movie: %s\n\n", new_videos[i].actor);

nFound++;
}
}

if ( !nFound)
{
printf("No movies or actors matching your description were found!");
}
Show_Menu(); /* Show display Menu to allow for customer input */

}

(This also fixes the issue that the menu is printed after every loop iteration ;-)
0
 

Author Comment

by:maplah
ID: 2562677
jkr,

That did the trick!  

I was wondering if I increase the points to 300, could you help me with read/write the arrays to a file and then read them from a file after the program starts?

Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2562835
The following code will do that ;-)

void load_data()
{
FILE* fp = NULL;

fp = fopen ( "video.dat", "rb");

if ( !fp) return;

while ( fread ( ( void*) &new_videos[Video_Current], sizeof ( video_t), 1, fp))
{
Video_Current++;
}

fclose ( fp);

printf ( "Loaded %d records\n", Video_Current);
}

void save_data()
{
int i;
FILE* fp = NULL;

fp = fopen ( "video.dat", "wb");

if ( !fp) return;

for ( i = 0; i < Video_Current; i++)
{
fwrite ( ( void*) &new_videos[i], sizeof ( video_t), 1, fp);
}
fclose ( fp);
printf ( "Saved %d records\n", Video_Current);
}

int main(void)
{
int menu_val;

Show_Menu();/*Display Menu first thing! - allow customer input */

load_data();

while((menu_val = getchar()) != '0')
{
getchar();
switch (menu_val)
{

case '1':
find();
break;

case '2':
check_out();
break;

case '3':
return_videos();
break;

case '4':
find_videos();
break;

case '5':
add_videos();
break;

case '6':
print_inventory();
break;

case '7':
Show_Menu();
break;

case '8':
save_data();
exit(1);
break;

default:
printf("Your selection did not match one of the menu options.\n I do not under stand %d \nPlease enter a valid option. \n", menu_val);
break;
}

}

NOTE that 'video.dat' will be created/has to reside in the working directory of your app, unless you specify an absolute path or use a command line argument as the file name/path...
0
 

Author Comment

by:maplah
ID: 2562895
jkr,

What happens if there is not instance of, or the .dat file has not been created?

How will the code react if it looks to open a file that doesn't exist?

Would it be possible to add to the menu an option to open as well as close (on exit)?

Just curious...

Thanks,

maplah
0
 

Author Comment

by:maplah
ID: 2562907
jkr,

Ignore my last comment - working through the code and compiling it (then running it) it made the logic of it clear.

I have one last question that will bump up the points to 400...


How could I keep users from entering strings that are too long - that would over write memory locations - when entering data for like Title, Type, and Actors?

Thanks,

maplah
0
 

Author Comment

by:maplah
ID: 2562925
jkr,

I don't think my last entry explained what I needed sufficiently:

The program must not blow up if a long string is entered - it should silently truncate the input. The title and status fields for a video are mandatory - something must be entered.  The program should not allow these fields to stay empty.

All file operations must be checked for errors and give a useful message to stderr when errors occur.

If an out-of-range option is entered at a menu, print a message describing the problem and allow  re-entering of the option.

Termination of data entry should be allowed, at least once per video entry.  For example, entering an empty title could be the signal to terminate data entry.

The program should not exit on a user error.  If there is an internal error (eg, unable to allocate memory), the program can exit, but other than that, the program should only terminate when the user tells it to.

Does this make more sense?  I originally offered 200 points - this would make it worth 490 points.

Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2562934
>>What happens if there is not instance of, or the .dat file
>>has not been created?

Nothing ;-)

Zero records are loaded, and the program will behave as usual...

To keep users from entering strings that are too long, you have several options:

- use a length format specifier in 'scanf()', e.g

scanf ( "%8s", string); /* will allow 8 chars */

or

scanf ( "%*s", MAX_CHARS, string); /* will allow MAX_CHARS chars */

- use 'fgets()' instead of 'gets()', as it allows to specify a maximum size, e.g.

char string[ BUF_SIZE + 1];
fgets ( string, BUF_SIZE , stdin);

string[ BUF_SIZE + 1] = '\0'; /* don't forget to add a trailing binary zero */


Oh, yes, one thing:

change 'load_data()' to read

void load_data()
{
FILE* fp = NULL;

fp = fopen ( "video.dat", "rb");

if ( !fp) return;

while ( fread ( ( void*) &new_videos[Video_Current], sizeof ( video_t), 1, fp))
{
Video_Current++;
if ( Video_Current >= Max_Value) break;
}

fclose ( fp);

printf ( "Loaded %d records\n", Video_Current);
}

This will ensure that you can't load data which exceeds the array size...
0
 
LVL 86

Expert Comment

by:jkr
ID: 2562948
Sorry, was typing when you submitted your comment - in this case, you might want to use your uwn string input function, e.g.

void read_string ( char* buf, int bufsiz)
{
size_t bytes_read;
static char acInput [ MAX_INPUT_BUFFER];

for ( ;;)
{
bytes_read =  fread ( acInput, sizeof ( char), MAX_INPUT_BUFFER, stdin);

if ( bytes_read > bufsiz)
{
 printf ( "The string you entered id too long - please try again or type '!quit'\n");
}
else break;
}

if ( strcmp ( acInput, "!quit")) /* only copy if not '!quit' */
strcpy ( buf, acInput);

}

to deal with the I/O error problem,use

#include <errno.h>

void load_data()
{
FILE* fp = NULL;

fp = fopen ( "video.dat", "rb");

if ( !fp)
{
 fprintf ( stderr, "ERROR opening file, reason == %d\n", errno);
 return;
}

while ( fread ( ( void*) &new_videos[Video_Current], sizeof ( video_t), 1, fp))
{
Video_Current++;
if ( Video_Current >= Max_Value) break;
}

fclose ( fp);

printf ( "Loaded %d records\n", Video_Current);
}

void save_data()
{
int i;
FILE* fp = NULL;

fp = fopen ( "video.dat", "wb");

if ( !fp)
{
 fprintf ( stderr, "ERROR opening file, reason == %d\n", errno);
 return;
}

for ( i = 0; i < Video_Current; i++)
{
fwrite ( ( void*) &new_videos[i], sizeof ( video_t), 1, fp);
}
fclose ( fp);
printf ( "Saved %d records\n", Video_Current);
}

0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:maplah
ID: 2562963
jkr,

How would I implement what you suggest in the following function?

/* This option allows you to add videos to the array */
void add_videos(void)
 {
fflush(stdin);
printf("\nEnter the title of the video?  ");
                   gets(new_videos[Video_Current].title);
printf("\nWhat genre is the video?  ");
                   gets(new_videos[Video_Current].type);
printf("\nEnter up to three actors separated by spaces:  ");
                   gets(new_videos[Video_Current].actor);
 Video_Current++; /* Video_Current = Video_Current + 1; */
 /* Move on to next video... */
 Show_Menu(); /* Display menu to allow for customer input */
}

I do not want to screw it up...

Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2563260
Well, e.g. by using

/* This option allows you to add videos to the array */
void add_videos(void)
 {
fflush(stdin);
printf("\nEnter the title of the video?  ");
                   read_string(new_videos[Video_Current].title, MAX_TITLE);
printf("\nWhat genre is the video?  ");
                   read_string(new_videos[Video_Current].type, MAX_TYPE);
printf("\nEnter up to three actors separated by spaces:  ");
                   read_string(new_videos[Video_Current].actor, MAX_ACTOR);
 Video_Current++; /* Video_Current = Video_Current + 1; */
 /* Move on to next video... */
 Show_Menu(); /* Display menu to allow for customer input */
}
0
 

Author Comment

by:maplah
ID: 2563565
jkr,

Could I apply the read_string function to all input lines of code?

Thanks,

maplah
0
 

Author Comment

by:maplah
ID: 2563575
jkr,

This line is throwing an error:

if ( bytes_read > bufsiz)

Here is the error:

warning C4018: '>' : signed/unsigned mismatch

It seems to make sense greater than, but why is it throwing an error?

Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2564852
Again, it's only a warning ;-)

It is because 'size_t' is 'unsigned', whereas 'int' is signed - to remedy this, use

if ( bytes_read > ( unsigned int) bufsiz)

(Hmm, I seem to have troubles with the email notification...)
0
 

Author Comment

by:maplah
ID: 2565825
jkr,

Thanks - I was wondering about using this to catch other large string input - would I be able to use this function else where?  Does the MAX_INPUT_BUFFER size need to be the same as the defined array sizes?

Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2566077
>>Does the MAX_INPUT_BUFFER size need to be the same as the
>>defined array sizes?

I'd make it about twice as large to prevent errors. As there's only a single instance of this buffer (and memory doesn't matter nowadays ;-) , you can make it as large as you want to - just imagine a user typing in a 8192 character title <s>
0
 

Author Comment

by:maplah
ID: 2566124
jkr,

it does not seem to be working - if I type in a string that is too long - it doesn't do anything - I have to hit the escape control + z and then it will ask for the type of video...

Did I screw something up:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

#define MAX_TITLE 160      /* Establishes Maximum for Video Titles */
#define MAX_TYPE 160       /* Establishes Maximum for Video Type */
#define MAX_ACTOR 160      /* Establishes Maximum for Video Actors */
#define Max_Value 510      /* Establishes Maximum for Array that stores video information */
#define CUST_NAME 160      /* Establishes Maximum for Customer Name */
#define CUST_VIDEO 160      /* Establishes Maximum for Video Checkout */
#define Max_Cust 510      /* Establishes Maximum for Array that stores video checkout info */
#define MAX_INPUT_BUFFER 160      /* Establishes Maximum for error control on string input */

/* Array that will hold video information */
typedef struct videos_s
{
      char title [ MAX_TITLE ];
      char type  [ MAX_TYPE ];
      char actor [ MAX_ACTOR ];
} video_t;

/* Array that will hold video check out information */
typedef struct checkout_s
{
      char name [ CUST_NAME ];
      char video  [ CUST_VIDEO ];
} checkout_t;

/*Declare all functions of program! */
void find(void);
void check_out(void);
void return_videos(void);
void find_videos(void);
void add_videos(void);
void print_inventory(void);
void menu_header(void);

/*This function displays the menu! */
void Show_Menu(void);

/*Define Global Variables! */
video_t new_videos[Max_Value];
checkout_t new_checkout[Max_Cust];

int Video_Current=0; /*Initialize current video to 0 */
int Video_Checkout=0; /*Initialize checkout video to 0 */

/* Code for read/write capabilities */
/* Loads data from storage file */
void load_data()
{
      FILE* fp = NULL;
      
      fp = fopen ( "video.dat", "rb");
      
      if ( !fp)
      {
            fprintf ( stderr, "ERROR opening file, reason == %d\n", errno);
            return;
      }
      
      while ( fread ( ( void*) &new_videos[Video_Current], sizeof ( video_t), 1, fp))
      {
            Video_Current++;
            if ( Video_Current >= Max_Value) break;
      }
      
      fclose ( fp);
      
      printf ( "Loaded %d records\n", Video_Current);
}

/* Loads data previously saved into storage file */
void save_data()
{
      int i;
      FILE* fp = NULL;
      
      fp = fopen ( "video.dat", "wb");
      
      if ( !fp)
      {
            fprintf ( stderr, "ERROR opening file, reason == %d\n", errno);
            return;
      }
      
      for ( i = 0; i < Video_Current; i++)
      {
            fwrite ( ( void*) &new_videos[i], sizeof ( video_t), 1, fp);
      }
      fclose ( fp);
      printf ( "Saved %d records\n", Video_Current);
}

void read_string ( char* buf, int bufsiz)
{
      size_t bytes_read;
      static char acInput [ MAX_INPUT_BUFFER];
      
      for ( ;;)
      {
            bytes_read =  fread ( acInput, sizeof ( char), MAX_INPUT_BUFFER, stdin);
            
            if ( bytes_read > ( unsigned int) bufsiz)
            {
                  printf ( "The string you entered is too long - please try again or type '!quit'\n");
            }
            else break;
      }
      
      if ( strcmp ( acInput, "!quit")) /* only copy if not '!quit' */
            strcpy ( buf, acInput);
      
}

int main(void)
{
      int menu_val; /* Initializes menu variable for switch statement */
      
      Show_Menu(); /*Display Menu first thing! - allow customer input */
      
      load_data();
      
      while ((menu_val = getchar()) != '0')  /* if slection is good do it! */
      {
            getchar();
            switch (menu_val)
            {
                  
            case '1': /* Allows for searching of video array for titles or actors */
                  find();
                  break;
                  
            case '2': /* Allows for checking out of videos - writes info to array */
                  check_out();
                  break;
                  
            case '3': /* Allows for the return of videos - clears info from array */
                  return_videos();
                  break;
                  
            case '4': /* Allows user to see what videos are checked out */
                  find_videos();
                  break;
                  
            case '5': /* Allows user to enter videos into video array */
                  add_videos();
                  break;
                  
            case '6': /* Prints all videos in video storage array */
                  print_inventory();
                  break;
                  
            case '7': /* Function displays menu */
                  Show_Menu();
                  break;
                  
            case '8': /* This function does two things - exits from program and stores video data
                               entered into video array */
                  save_data();
                  exit(1);
                  break;
                  
            default: /* If bad number entered into menu selection kicks out error message
                              and asks for another number */
                  printf("Your selection did not match one of the menu options.\n I do not under stand %d \nPlease enter a valid option. \n", menu_val);
                  break;
            }
            
      }
      
      return(0);
}
/* This option will allow you to search for a video by entering a fragment of a video or title,
type or actors */
void find(void)
{
      
      int nFound = 0;
      int i;
      char search[1024];
      char title[1024];
      char actor[1024];
      char* pc;
      
      printf("\n\n"); /* Just to space it out a second! */
      
      /* Ask for user input for search function */
      fflush(stdin);
      printf("\nSearch for a video title or actor name\nEnter either full or partial info: ");
      scanf("%s", search);
      
      for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
      {
            
            /* use a local copy */
            strcpy ( title, new_videos[i].title);
            strcpy ( actor, new_videos[i].actor);
            
            /* make both search items and string to search lowercase */
            pc = search;
            while ( *pc)
            {
                  *pc = (char) tolower ( (int)*pc);
                  pc++;
            }
            
            pc = title;
            while ( *pc)
            {
                  *pc = (char) tolower ( (int)*pc);
                  pc++;
            }
            
            pc = actor;
            while ( *pc)
            {
                  *pc = (char) tolower ( (int)*pc);
                  pc++;
            }
            
            if ( strstr( title, search) || strstr(actor, search))
            {
                  /* found a match either in actor or title */
                  fflush(stdin);
                  printf("Title of movie or actor's name: %s\n", new_videos[i].title);
                  printf("Actors in movie: %s\n\n", new_videos[i].actor);
                  
                  nFound++;
            }
      }
      
      if ( !nFound)
      {
            printf("No movies or actors matching your description were found!");
      }
      Show_Menu(); /* Show display Menu to allow for customer input */
      
}

/* This option lets you check videos out to a customer */
void check_out(void)
{
   int vid;
   int i;
   
   printf("\nEnter how many videos do you want to check out? ");
   scanf("%d", &vid);
   
   for(i = 0; i < vid; i++)
     {
      fflush(stdin);
      printf("\nEnter customer name (Last name, First name): ");
      gets(new_checkout[Video_Checkout].name);
      printf("\nEnter video name: ");
      gets(new_checkout[Video_Checkout].video);
      Video_Checkout++; /* Video_Checkout = Video_Checkout + 1; */
     }
   /* Move on to next customer checkout... */
   Show_Menu(); /*Display Menu to allow for customer input */
}

/* This option allows you to check the videos back in */
void return_videos(void)
{
      int i;
      char cust_name[30];
      
      /* Only loops till hits last video inputted. */
      printf("\n\n"); /* Just to add some space between entries */
      
      printf("\nEnter customer Name (Last name, First name): ");
      gets(cust_name);
      
      for(i = 0; i < Video_Checkout; i++) /* Loop until last video that was entered */
      {
            if (!strcmp(cust_name, new_checkout[i].name))
            {
                  printf("%s is checked back in - Thank You!\n", new_checkout[i].video);
                  /* Clear video from array */
                  strcpy(new_checkout[i].name, "");
                  strcpy(new_checkout[i].video, "");
            }
            else
            {
                  printf("\nThe customer ID Number entered was not found!\nPlease try again.\n");
            }
      }
      Show_Menu(); /*Display Menu to allow for customer input */
}

/* This option allows you to title or actor name, and see a list of videos that are checked out */
void find_videos(void)
{
      char name[30];
      int i;
      
      printf("Enter customer name Last name, First name): ");
      gets(name);
      
      for (i = 0; i < Video_Checkout; i++)
      {
            if (!strcmp(name, new_checkout[i].name))
            {
                  printf("Video: [%s]\n", new_checkout[i].video);
            }
      }
      
      Show_Menu(); /* Display menu to allow for customer input. */
}

/* This option allows you to add videos to the array */
void add_videos(void)
{
      fflush(stdin);
      printf("\nEnter the title of the video?  ");
      read_string(new_videos[Video_Current].title, MAX_TITLE);
      printf("\nWhat genre is the video?  ");
      read_string(new_videos[Video_Current].type, MAX_TYPE);  
      printf("\nEnter up to three actors separated by spaces:  ");
      read_string(new_videos[Video_Current].actor, MAX_ACTOR);
      Video_Current++; /* Video_Current = Video_Current + 1; */
      /* Move on to next video... */
      Show_Menu(); /* Display menu to allow for customer input */
}

/* This option allows you to print all of the titles in the inventory */
void print_inventory(void)
{
      int i;
      
      /* Only loops till hits last video inputted. */
      printf("\n\n\n"); /* Just to space it out a second! */
      for(i = 0; i < Video_Current; i++) /* Loop until last video that was entered */
      {
            printf("Title of movie: %s\n", new_videos[i].title);
            printf("Type of move: %s\n", new_videos[i].type);
            printf("Actors in movie: %s\n\n", new_videos[i].actor);
      }
      Show_Menu(); /*Display Menu to allow for customer input */
}

void Show_Menu(void)
{
      printf( "\nSCHLOCKLUSTER VIDEO                       -  MAIN MENU: \n\n");
      printf( "DESCRIPTION/FUNCTION:                        ENTER NUMBER (Then hit enter): \n");
      printf( "Find video(s) (by title, type, or actors) -       1 \n");
      printf( "Check out video(s)                        -       2 \n");
      printf( "Return video(s)                           -       3 \n");
      printf( "Find all videos out to a customer         -       4 \n");
      printf( "Add new video(s)                          -       5 \n");
      printf( "Print inventory list (sorted by...)       -       6 \n");
      printf( "Print Main Menu again                     -       7 \n");
      printf( "To Exit Program Enter 8                   -       8 \n\n");       
}

thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2566167
You're correct, I forgot that 'fread()' required an stream terminator - use 'fgets()' instead, e.g.

void read_string ( char* buf, int bufsiz)
{
static char acInput [ MAX_INPUT_BUFFER];

for ( ;;)
{
fgets ( acInput, MAX_INPUT_BUFFER, stdin);

if ( strlen ( acInput) >  bufsiz)
{
printf ( "The string you entered is too long - please try again or type '!quit'\n");
}
else break;
}

if ( strcmp ( acInput, "!quit")) /* only copy if not '!quit' */
strcpy ( buf, acInput);

}


(tested it ;-)
0
 

Author Comment

by:maplah
ID: 2566536
jkr,

It did not work - I entered a long string and it printed out the next line asking for type of video and then next line asking for actors... I must have goofed something up... I will append the function and the function that calls it at the end...

how would I apply the read_string function to the other functions that ask for input to be stored in an array?

Like the video check out?

also, how would I keep someone from entering a blank string for any of the functions that ask for input?  A blank line throws up an error and gives them the option to quit...

void read_string ( char* buf, int bufsiz)
{
      static char acInput [ MAX_INPUT_BUFFER];
      
      for ( ;;)
      {
            fgets ( acInput, MAX_INPUT_BUFFER, stdin);

            if ( strlen ( acInput) >  ( unsigned int) bufsiz)
               {
                printf ( "The string you entered is too long - please try again or type '!quit'\n");
               }
            else break;
      }
      
      if ( strcmp ( acInput, "!quit")) /* only copy if not '!quit' */
            strcpy ( buf, acInput);
      
}

void add_videos(void)
{
      fflush(stdin);
      printf("\nEnter the title of the video?  ");
      read_string(new_videos[Video_Current].title, MAX_TITLE);
      printf("\nWhat genre is the video?  ");
      read_string(new_videos[Video_Current].type, MAX_TYPE);  
      printf("\nEnter up to three actors separated by spaces:  ");
      read_string(new_videos[Video_Current].actor, MAX_ACTOR);
      Video_Current++; /* Video_Current = Video_Current + 1; */
      /* Move on to next video... */
      Show_Menu(); /* Display menu to allow for customer input */
}

Thanks,

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2566565
void read_string ( char* buf, int bufsiz)
{
static char acInput [ MAX_INPUT_BUFFER];

for ( ;;)
{
fgets ( acInput, MAX_INPUT_BUFFER, stdin);

if ( !strlen ( acInput))
{
printf ( "You entered an empty string - please try again or type '!quit'\n");
continue;
}

if ( strlen ( acInput) >  bufsiz)
{
printf ( "The string you entered is too long - please try again or type '!quit'\n");
continue;
}

break;
}

if ( strcmp ( acInput, "!quit")) /* only copy if not '!quit' */
strcpy ( buf, acInput);

}

Hmm, I tried it here, and it works - maybe you pass in a buffer size that does not match?
0
 
LVL 86

Expert Comment

by:jkr
ID: 2566571
Well, maybe we should close this Q and settle the rest using mails - this thread gets a pain to load...
0
 

Author Comment

by:maplah
ID: 2566696
jkr,

n2chiles@uswest.net

Good idea...

maplah
0
 
LVL 86

Expert Comment

by:jkr
ID: 2567171
I'm disappointed - does 'Sam' still like his 'Pokemon' cards?

Who are you - 'mapper', 'maplah' or 'n2chiles'?

I don't know how to handle this ...

I suggest you ask CS for the deletion of two of the above accounts.
0
 

Author Comment

by:maplah
ID: 2567206
jkr,

I am sorry that you feel this way.  I am using this only as a last resort.

I guess when you have the knowledge it's pretty easy to play GOD...

What ever...

map
0
 

Author Comment

by:maplah
ID: 2567366
Adjusted points to 300
0
 

Author Comment

by:maplah
ID: 2567367
jkr,

you are right!  I used the services to help extract myself out of a bad situation.  

It wasn't right, but the situation (to me) seemed to warrant my actions.

Sam is fine (http://www.users.uswest.net/~n2chiles) then on Sam's Page to see him (he does exist!).

I took this course to see if I had any skill in C programming, but my wife got sick and I missed two weeks of courses in order to stay home with the boys so she could get better.  I got way behind and the course ended and the instructor gave me two weeks to make up, but I could not seem to grasp the skills requied to do what he wanted.  I tried - I really did!  However, I just could not seem to keep or retain what I was readin and could not do what was requied to pass the course.   I would have had to pay my job back $1000.00 if I did not pass this course.  That's why I did what I did - even though it was wrong.  

That's not your problem.  I new when you asked for my e-mail that this was going to happen, but I figured - that the way I presented the question and (I new you had helped before - so, I knew you knew me!) the easy way you responded that I figured you had to know what I was doing.  That's why I did not hesitate in providing you my information to you.  You make think I am a cheat but why did I NOT hide who I was from you??  

Think what ever you want - I got myself into this situation and now (thanks to you for waking me up - will either fall on my face or pass the course - the only problem is explaining to Sam and Morgan why (if I don't pass and have to pay the money back) why we can't go out for our bi-weekly movies and burgers (because I won't be able to afford it if I have to pay back the money - that I don't have by the way - since I am the only one in the family that works)) - but, I think that is a just punishment for trying to take the easy way out.

jkr, thanks for ringing the bell and waking me up the realities of life!

I do appreciate your help.

thanks,

map (my real initials!)

0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now