Thread: Need Help Debugging Array Program

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    116

    Need Help Debugging Array Program

    Hey guys:

    ***NOTE***: THIS PROGRAM WAS CREATED USED WITH THE KNOWLEDGE OF THE BASICS OF LOOPS AND ARRAYS.

    I need help debugging my code. It compiles fine, but there are some problems with input and outputing stuff in arrays. This is an address storage system. A max number of address to be stored is 10.

    The inputs are put into an array then transfered into a multidimensional array which helps sort the different locations of address stored.

    DO NOT MIND CASE D or E, it is not finished. I need to focus on debugging A, B, and C.

    CASE A: seems to work fine, I can add multiple address and it seems to work fine.

    CASE B: When I try to edit an address (like the 1st address stored), everything is displayed correctly. But when I save it, and try and edit it again, only the first character of each array displays in the parenthesis. When I search for it, it shows only the first character. I can not figure out what is happening when I'm transferring the information from a temp section of the array to the address location I want it in. CAN YOU HELP ME OUT???

    CASE C: When I have two address that are fairly similar (ie: david .... david3), david3 will show up correctly, but david will not. How can I fix this?

    -----------------

    I think those are the main problems right now, if you could help out I would really appreciate it. I've been working on this program for the past couple of days, and my mind is sort of going blank. Thanks!!!

    ----------------

    Code:
    #include<stdio.h>
    #include<stdbool.h>
    #define M 11
    #define N 15
    
    int main(void)
    {
      int i, j, k, temp, addr_temp, addr_num, index_temp, delete_index, age2, age[M][1];
      char input, save, save2, delete, name[M][N], city[M][N], name2[N], city2[N], search[N], phone[M][N], phone2[N];
      bool are_equal, location_exist;
    
      do{
    
        printf("\n**********Main Menu************");
        printf("\nAdd an address        (press a)");
        printf("\nEdit an address       (press b)");
        printf("\nSearch an address     (press c)");
        printf("\nDelete an address     (press d)");
        printf("\nList all addresses    (press e)");
        printf("\nExit                  (press f)");
        printf("\n*******************************\n\n");
    
        scanf(" %c", &input);
    
        switch(input)
          {
          case('a'):
            {
              printf("\n**************Add Address************\n");
              printf("Enter nickname: ");
    	  
    	  scanf("%s", name2);
    	  for(i=0; i< M-1; i++)
    	    {
    	      if(name[i][0] == 0)
    		{
    		  addr_temp = i;
    		  j=0;
    		  do
    		    {
    		      name[i][j] = name2[j];
    		      j++;
    		    }
    		  while(name2[j] != '\0');
    
    		  break;
    		}
    	      else
    		continue;
    	    }
           
    	    printf("Enter age: ");
           age: scanf("%d", &age2);
    
    	    if((age2 >= 1) && (age2 <= 140))
    		age[addr_temp][0] = age2;			    
    
    	    else
    	      {
    		printf("\nPlease input correct data\n");
    		goto age;
    	      }
    	    
    	    printf("Enter city: ");
    	    scanf("%s", city2);
    
    	    if(city[addr_temp][0] == 0)
    		{
    		  j=0;
    		  do
    		    {
    		      city[addr_temp][j] = city2[j];
    		      j++;
    		    }
    		  while(city2[j] != '\0');
    		}
    
    	      	    
    	    printf("Enter phone: ");
    	    scanf("%s", phone2);
    	    
    	    j=0;
    	    do
    	      {
    		phone[addr_temp][j] = phone2[j];
    		j++;
    	      }
    	    while(phone2[j] != '\0');
    
    	    printf("Save(y/n): ");
    	    scanf(" %c", &save);
    	    
    	    if(save =='n')
    	      {
    		age[addr_temp][0] = 0;
    		for(j=0; j< N; j++)
    		  {
    		    name[addr_temp][j] = 0;
    		    city[addr_temp][j] = 0;
    		    phone[addr_temp][j] = 0;
    		  }
    		printf("\nRecord not added...");
    	      }
    
    	    if(save == 'y')
    	      printf("\nRecord added...");
    	
    	    for(j=0; j< N; j++)                 //CLEANS THE TEMP HOLDERS
    	      {
    		name2[j] = 0;
    		phone2[j] = 0;
    		city2[j] = 0;
    	      }
    
    	    break;
    	}
    
          case ('b'):
    	{
    	  printf("\n**********Edit an address*************");
    	  printf("\nEnter address number: ");
    	  scanf("%d", &addr_num);
    	  printf("\n");
    	  addr_num = addr_num - 1;
    	  
    	  for(j=0; j< N; j++)                 //CLEANS THE TEMP HOLDERS                                                    
    	    {
    	      name2[j] = 0;
    	      name[10][j] = 0;
    	      phone2[j] = 0;
    	      phone[10][j] = 0;
    	      city2[j] = 0;
    	      city[10][j] = 0;
    	    }
    	  
    	  if((age[addr_num][0] != 0) && (addr_num >= 0) && (addr_num <=9))
    	    {
    	     
    	      printf("Enter new nickname(");            
    	      j=0;
    	      do
    		{
    		  printf("%c", name[addr_num][j]);
    		  j++;
    		}
    	      while(name[addr_num][j] != '\0');
    	      
    	      printf("): ");
    	      scanf("%s", name2);
    
    	      j=0;
    	      do
    		{
    		  name[10][j] = name2[j];
    		  j++;
    		}
    	      while(name[10][j] != '\0');
    	  			  
    
    	      printf("Enter new age(%d): ", age[addr_num][0]);
            age2: scanf("%d", &age2);
    	      
    	      if(age2 >= 1 && age2 <= 140)
                    age[10][0] = age2;
    
    	      else
    		{
    		  printf("\nPlease input correct data\n");
    		  goto age2;
    		}
    
    
    	      printf("Enter new city(");
    	      j=0;
    	      do
    		{
                      printf("%c", city[addr_num][j]);
                      j++;
                    }
    	      while(city[addr_num][j] != '\0');
                  
    	      printf("): ");
    	      scanf("%s", city2);
    	      
    	      j=0;
    	      do
    		{
    		  city[10][j] = city2[j];
    		  j++;
    		}
    	      while(city[10][j] != '\0');
    	      
    	      printf("Enter new phone(");
    	      j=0;
    	      do
    		{
                      printf("%c", phone[addr_num][j]);
                      j++;
                    }
    	      while(phone[addr_num][j] != '\0');
    	      
                  printf("): ");
    	      scanf("%s", phone2);
    
    	      j=0;
    	      do
    		{
    		  phone[10][j] = phone2[j];
    		  j++;
    		}
    	      while(phone[10][j] != '\0');
    	      
    	      printf("Save(y/n): ");
    	      scanf(" %c", &save2);
    	      
    	      if(save2 =='y')
    		{
    		  age[addr_num][0] = 0;
    		  age[addr_num][0] = age[10][0];
    		  age[10][0] = 0;
    		  for(j=0; j< N; j++)
    		    {
    		      name[addr_num][j] = 0;
    		      name[addr_num][j] = name[10][j];
    		      name[10][j] = 0;
    		      city[addr_num][j] = 0;
    		      city[addr_num][j] = city[10][j];
    		      city[10][j] = 0;
    		      phone[addr_num][j] = 0;
    		      phone[addr_num][j] = phone[10][j];
    		      phone[10][j] = 0;
    		    }
    		}
    
    	      if(save2 =='n')
    		{
    		  age[10][0] = 0;
    		  for(j=0; j< N; j++)
    		    {
    		      name[10][j] = 0;
    		      city[10][j] = 0;
    		      phone[10][j] = 0;
    		    }
    		}
    	    }
    
    	 else
    	   printf("\nAddress not found...");
       
    	  break;
    	}
    
          case('c'):
    	{
    	  printf("\n***********Search an address************");
    	  printf("\nEnter nickname to search: ");
    	  scanf("%s", search);
    	  
    	  j=0;
    	  for(i=0; i< M-1; i++)
    	    {
    	      while(search[j] == name[i][j] && search[j] != '\0' && name[i][j] != '\0')
    		j++;
    
    	      if(search[j] == '\0' && name[i][j] == '\0')
    		{
    		  are_equal = true;
    		  index_temp = i;
    		  break;
    		}
    	      
    	      else if(search[0] == 0 && name[i][0] == 0)
    		continue;
    
    	      else
    		are_equal = false;
    	    }
    
    	  if(are_equal == false)
    	    {
    	      printf("\nNickname does not exist, address not found");
    	      goto end;
    	    }
    
    	  if(are_equal = true)
    	    {
    	  
    	  printf("\nResult:");
    	  printf("\nNickname: ");
    	  
    	  j=0;
    	  do
    	    {
    	      printf("%c", name[index_temp][j]);
    	      j++;
    	    }
    	  while(name[index_temp][j] != '\0');
    	  
    
    	  printf("\nAge: %d", age[index_temp][0]);
    
    	  printf("\nCity: ");
    	  
    	  j=0;
    	  do
    	    {
    	      printf("%c", city[index_temp][j]);
    	      j++;
    	    }
    	  while(city[index_temp][j] != '\0');
    	  
    	  printf("\nPhone: ");
    
    	  j=0;
    	  do
    	    {
    	      printf("%c", phone[index_temp][j]);
    	      j++;
    	    }
    	  while(phone[index_temp][j] != '\0');
    
    	    }
    
    	  printf("\n*************************************");
    
    	  break;
    	}
    
          case('d'):
    	{
    	  printf("\n***********Delete an Address************");
    	  printf("\nEnter address number to delete: ");
    	  scanf("%d", delete_index);
    
    	  delete_index = delete_index - 1;
    
    	  printf("\nNickname: ");
    	  j=0;
    	  while(name[delete_index][j] != '\0')
    	    {
    	      printf("%c", name[delete_index][j]);
    	      j++;
    	    }
    
    	  
    	  printf("\nAge: %d", age[delete_index][0]);
    
    	  printf("\nCity: ");
    	  j=0;
              while(city[delete_index][j] != '\0')
                {
                  printf("%c", city[delete_index][j]);
                  j++;
                }
    
    	  printf("\nPhone: ");                              //NEED TO CHECK
    	  j=0;
              while(phone[delete_index][j] != '\0')
                {
                  printf("%c", phone[delete_index][j]);
                  j++;
                }
    
    	  printf("\nAre you sure(y/n): ");
    	  scanf(" %c", &delete);
    
    	  if(delete == 'y')
    	    {
    	      age[delete_index][0] = 0;
    	      for(j=0; j< N; j++)
    		{
    		  name[delete_index][j] = 0;
    		  city[delete_index][j] = 0;
    		  phone[delete_index][j] = 0;
    		}
    	      printf("\nAddress deleted");
    	    }
    
    	  if(delete == 'n')
    	    printf("\nAddress not deleted");
    
    	  break;
    	}
    
          case('e'):
    	{
    	  printf("\n*************List all address***************");
    	  
    	  printf("\nSN:\tNickname\tAge\tCity\tPhone");
    	  printf("\n\n");
    	  
    	  i=0;
    	  while(age[i][0] != 0)
    	    {
    	      i++;
    	    }
    
    
    
    
    
    
    
    
    
    
    	  break;
    	}
          
          case('f'):
    	break;
    
          }
    
    
      end: printf("\n");
    
      }
      while(input != 'f');
    
    
      return(0);
    }

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I hate this kind of code, and therefore won't look at it.

    When you have a SWITCH/CASE ladder, and each CASE block is long, call a function to work it out. This kind of code (show above) makes maintaining and debugging painful. I have to work through code like this in my day job, and I won't do it for fun. Sorry.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't really want to read this very carefully either, and I'll add the other advantage of using functions: since case 'a' works, you can re-use that, really, for case 'b' too.

  4. #4
    Registered User
    Join Date
    Feb 2008
    Posts
    116
    I just debugged CASE B: everything works fine for that...

    I'm looking at CASE C.

    CASE C: the problem I am having is when a word is similar like (david ....and....david3), david3 comes up fine with the info, but david comes up with garbage or nothing...

    If someone could take a look at that, that would be great!

  5. #5
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    i will make a few comments about some random things i see that could cause problems in your code.

    when you use "scanf", you are assuming the user will input a string < 15 characters. what if they input more than >= 15 characters? this is a buffer overflow and will cause unexpected results. you should look for a secure alternative to scanf. check out the FAQ here, you could try "fscanf" or "fgets".

    primitive datatypes are not initialized to any value automatically. this means that all of those "int" and "char" variables you have at the top will have an unknown value in it if you dont assign it any value. this is very bad and will easily lead to problems. i will do an example run-through of your code that will be a problem:
    - the menu is displayed
    - user enters character 'a' and enter to select add address
    - user enters "0123456789ABCDEF" as their nickname (notice there is ALREADY a buffer overflow with the name2 variable
    - now we go into the for loop. remember that since you didnt initialize any of your function variables (in particular 'name'), you dont know and are not guaranteed that it has any value (ie 0 or NULL), which you are using to determine that this string index is empty and you can write there. lets say that the value at name[0][0] is not zero (may very well happen), then control goes to the 'else' clause and this iteration is done (because of continue). lets say this happens for every name[i][0] in your for loop. notice this means that 'addr_temp' is NOT initialized
    - now we are prompted for age, we enter a valid age, say age = 15. the if will check that 1 <= age <= 140, which is true. now we are writing to location age[addr_temp][0]. this will have unexpected behaviour, as you do not know the value of addr_temp: maybe it is a valid index in your array, maybe it is "-15000", maybe it is "2500". this will likely segfault or crash some other way (or some other program).
    - also do not use 'goto's, they are bad form and makes the flow of logic difficult to follow. what you have can be accomplished using a looping structure instead: do not use 'goto'.
    - now we are asked to enter a city. of course we enter a city greater than you are expecting, and result in unexpected and undefined behaviour. also, you are writing to city[addr_temp][0], which will be bad in this example, just as above
    - now we, of course, enter a phone number too long to store in your array--bad.
    - what if we accidently enter 'x' when asked to save? it will not do either 'save' or 'not save', and we will not have the option to enter properly 'y' or 'n', as we initially wanted to. also, it will actually be 'saved,' the only difference is we wont get the printed confirmation.


    notice this was just after going through 'case a', which supposedly worked. so fix these, and im sure all other cases have very similar potential problems, too. maybe somewhere in that mess of problems will lie your bug.
    Last edited by nadroj; 10-01-2008 at 05:04 PM.

  6. #6
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Not sure what you meant by
    Code:
    	      if(search[j] == '\0' && name[i][j] == '\0')
    		{
    		  are_equal = true;
    		  index_temp = i;
    		  break;
    		}
    	      
    	      else if(search[0] == 0 && name[i][0] == 0)
    		continue;
    
    	      else
    		are_equal = false;
    You're first checking if you reached the end of both strings simultaneously. Then you're checking that condition again but this time comparing the first character to 0 (same as comparing with '\0' which was already covered).

    A lot of complexity can be eliminated if you learn about strcpy() and strcmp() functions.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Some further random "bad code" comments:

    Code:
    age2: scanf("%d", &age2);
    	      
    	      if(age2 >= 1 && age2 <= 140)
                    age[10][0] = age2;
    
    	      else
    		{
    		  printf("\nPlease input correct data\n");
    		  goto age2;
    		}
    This judge gives NIL point for this chunk of code (there are two nearly identicaly pieces). Really: it is not a good idea to form loops with goto. And if you MUST form loops with goto, don't use a label that has the same name as a variable - that is very confusing.

    Code:
    	  for(i=0; i< M-1; i++)
    	    {
    	      if(name[i][0] == 0)
    		{
    		  addr_temp = i;
    		  j=0;
    		  do
    		    {
    		      name[i][j] = name2[j];
    		      j++;
    		    }
    		  while(name2[j] != '\0');
    
    		  break;
    		}
    	      else
    		continue;
    	    }
    Don't know what your thoughts are about "continue", but in this case, it serves absolutely no purpose, as it's at the end of a loop that would "continue" anyways - it does absolutely nothing other than take up two lines of code to confuse you and anyone else reading the code. Pointless.

    Code:
    		      name[addr_num][j] = 0;
    		      name[addr_num][j] = name[10][j];
    The first line here is another example of pointless code - you set the position in the array to zero, only to immediately overwrite it with name[10][j] - which is either zero and thus the first line has no effect, or it's not zero, so it will overwrite the zero that you just put in.

    Code:
    	    for(j=0; j< N; j++)                 //CLEANS THE TEMP HOLDERS
    	      {
    		name2[j] = 0;
    		phone2[j] = 0;
    		city2[j] = 0;
    	      }
    You only need to set the first char to zero to empty a string, so name2[0] = 0 would suffice to make name2 an empty string.

    Do not take this as a criticism of you as a person, but the work you have done is a learning process, and if no one points out where you can do better, it's not going to get better.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Code:
    		      name[addr_num][j] = 0;
    		      name[addr_num][j] = name[10][j];
    The first line here is another example of pointless code - you set the position in the array to zero, only to immediately overwrite it with name[10][j] - which is either zero and thus the first line has no effect, or it's not zero, so it will overwrite the zero that you just put in.
    also, it seems possible that 'addr_num" can take on the value 10, in which case the code will do: name[addr_num][j] = name[10][j] = 0. as i mentioned above, i havent gone through all of the code or the entire picture, so i dont really know what the above 2 statements are supposed to do. ie if it is supposed to erase the first string then ok. also, if you declared a constant at the beginning of your code for the size of the array and later change it from 11 to 8, for example, you may forget to change the "name[10]"s to "name[7]"s. use your constant--thats why you created it!
    Last edited by nadroj; 10-01-2008 at 05:35 PM.

  9. #9
    Registered User
    Join Date
    Feb 2008
    Posts
    116
    1) I know about the scanf if... it will be assumed that the user inputs less than 15 characters, so it will not overflow. (remember, this is a somewhat basic program with basic knowledge for a beginning programming class)

    2) the else; continue; is just for me to read the code more easily and quickly. It's sort of just a helper for me...

    3) Thank you for all your comments, I'm going to try and work on it tonight!

  10. #10
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    ok. and i want to repeat what matsp said: we are not trying to pick on you, but to let you know about these things to make you a better programmer! i hope the suggestions given to you in this thread will allow you to fix your program.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 05-29-2009, 07:25 PM
  2. c++ a very simple program
    By amjad in forum C++ Programming
    Replies: 1
    Last Post: 05-27-2009, 12:59 PM
  3. Program Plan
    By Programmer_P in forum C++ Programming
    Replies: 0
    Last Post: 05-11-2009, 01:42 AM
  4. Replies: 7
    Last Post: 08-19-2007, 08:10 AM
  5. Type and nontype parameters w/overloading
    By Mr_LJ in forum C++ Programming
    Replies: 3
    Last Post: 01-02-2004, 01:01 AM