Unique-string check in C

tsj

tsj

Permabanned
Joined
7 May 2004
Posts
1,051
Location
United Kingdom
Code:
/** Enters Team Name **/
int initialise(team_info * arrdetails,
               const int numofteams)
{
        
  /** if not reading from file... **/
  int i;
  char rtn = 0;
  int j = 0;
      
  int num_teams = 0;
        
  for(i = 0; i < numofteams; i++)
  {
    char teamd[16];
        
    printf("\nPlease enter team name:\n>");
    scanf("%s%c", teamd, &rtn);
    /** gets(teamd); **/
    printf("i is %d", i);
        
    for(j = 0; j <= i; j++)
    {
      int match = strcmp(teamd, arrdetails[j].team);
     
      if(match == 0)
      {
        printf("Sorry, this team already exists. Please try again!");
        --i;
        break;
      }
         
      else if (match != 0)
      {
        strcpy(arrdetails[i].team, teamd);
        arrdetails[i].played = 0;
        arrdetails[i].won = 0;  
        arrdetails[i].lost = 0;
        arrdetails[i].draw = 0;
        arrdetails[i].points = 0;
        arrdetails[i].goalsfor = 0;
        arrdetails[i].goalsagainst = 0;
        arrdetails[i].goalsd = 0;
        arrdetails[i].team_id = num_teams;
        num_teams++;
        printf("writing team num %d", i);
      } 
    }
  
  }
  return num_teams;
}

I had this working before but now im getting this:

Code:
How many teams are in the league?
6
numofteams is 6
Please enter team name:
>liverpool
i is 0writing team num 0
Please enter team name:
>manchester
i is 1writing team num 1Sorry, this team already exists. Please try again!
Please enter team name:
>liverpool
i is 1Sorry, this team already exists. Please try again!
Please enter team name:
>arsenal
i is 1writing team num 1Sorry, this team already exists. Please try again!
Please enter team name:
>chelsea
i is 1writing team num 1Sorry, this team already exists. Please try again!
Please enter team name:
>blackburn
i is 1writing team num 1Sorry, this team already exists. Please try again!
Please enter team name:
>everton
i is 1writing team num 1Sorry, this team already exists. Please try again!
Please enter team name:
>wolves
i is 1writing team num 1Sorry, this team already exists. Please try again!
Please enter team name:
>birminghamcity
i is 1writing team num 1Sorry, this team already exists. Please try again!
Please enter team name:
>

Can anyone spot the problem?
 
Permabanned
Joined
19 Aug 2006
Posts
1,604
The code is a bit confusing....

I think it might be because i starts off as zero, so the second loop never runs so the first team is never added. It's quite hard to work out without having the code to mess around with.
 
Last edited:

tsj

tsj

Permabanned
OP
Joined
7 May 2004
Posts
1,051
Location
United Kingdom
happytechie said:
the loop with the counter j isn't being broken out of when you don't find a match....


Code:
    for(j = 0; j <= i; j++)
    {
      int match = strcmp(teamd, arrdetails[j].team);
      printf("\nmatch is %d", match);
      printf("\nteamd is %s and arrdetailsj is %s", teamd, arrdetails[j].team);
    
      if(match == 0)
      {
        printf("\nSorry, this team already exists. Please try again!");
        --i;
        break;
      }
  
      else if (match != 0)
      {
        strcpy(arrdetails[i].team, teamd);
        arrdetails[i].played = 0;
        arrdetails[i].won = 0;
        arrdetails[i].lost = 0;  
        arrdetails[i].draw = 0;
        arrdetails[i].points = 0;
        arrdetails[i].goalsfor = 0;
        arrdetails[i].goalsagainst = 0;
        arrdetails[i].goalsd = 0;
        arrdetails[i].team_id = num_teams;
        num_teams++;
        printf("\nwriting team num %d", i);
        break;
      }
    }

Just made some changes and it works... but now its not doing the lowercasing.

I want to change the string to lowercase, it does it for the first string i enter... but after that it doesnt.

Any ideas?
 

tsj

tsj

Permabanned
OP
Joined
7 May 2004
Posts
1,051
Location
United Kingdom
happytechie said:
what lowercasing dude?

I can't see anything in that code that is changing the strings you enter to all lowercase, but it's been a long long time since I wrote any C


woops missed a bit of code ... :p

Code:
/** Enters Team Name **/
int initialise(team_info * arrdetails,
               const int numofteams)
{
        
  /** if not reading from file... **/
  int i = 0;
  int j = 0;
  char rtn = 0;
  char *ptr = NULL;
  int num_teams = 0;
        
  for(i = 0; i < numofteams; i++)
  {
    char teamd[16];

    printf("\nPlease enter team name:\n>");
    scanf("%s%c", teamd, &rtn);
    /** gets(teamd); **/

    ptr = teamd;

    for(ptr=teamd;*ptr;ptr++)
    {
      *ptr=tolower(*ptr);
    }

    printf("you entered %s ptr is %s", teamd, ptr);

    printf("i is %d", i);

    for(j = 0; j <= i; j++)
    {
      int match = strcmp(teamd, arrdetails[j].team);
      printf("\nmatch is %d", match);
      printf("\nteamd is %s and arrdetailsj is %s", teamd, arrdetails[j].team);

      if(match == 0)
      {
        printf("\nSorry, this team already exists. Please try again!");
        --i;
        break;
      }

      else if (match != 0)
      {
        strcpy(arrdetails[i].team, teamd);
        arrdetails[i].played = 0;
        arrdetails[i].won = 0;
        arrdetails[i].lost = 0;
        arrdetails[i].draw = 0;
        arrdetails[i].points = 0;
        arrdetails[i].goalsfor = 0;
        arrdetails[i].goalsagainst = 0;
        arrdetails[i].goalsd = 0;
        arrdetails[i].team_id = num_teams;
        num_teams++;
        printf("\nwriting team num %d", i);
        break;
      }
    }

  }
  return num_teams;
}
 
Soldato
Joined
18 Oct 2002
Posts
5,600
Location
Surrey
that's horrid...

did you know that a character array is actually just a pointer to the first location in the array?

anyway....

the whole for loop with the pointer and the array looks wrong to me, I'm surprised that it even worked once

what about:

for(int foo = 0 ; foo < strlen(teamd); foo++){
teamd[foo] = tolower(teamd[foo];
}

remember that teamd is the same thing as teamd[0] at initialization which is actually just a pointer to the memory space where the first character of the array is stored.
 

tsj

tsj

Permabanned
OP
Joined
7 May 2004
Posts
1,051
Location
United Kingdom
happytechie said:
that's horrid...

did you know that a character array is actually just a pointer to the first location in the array?

anyway....

the whole for loop with the pointer and the array looks wrong to me, I'm surprised that it even worked once

what about:

for(int foo = 0 ; foo < strlen(teamd); foo++){
teamd[foo] = tolower(teamd[foo];
}

remember that teamd is the same thing as teamd[0] at initialization which is actually just a pointer to the memory space where the first character of the array is stored.


thanks for that mate. it works :D
 
Soldato
Joined
18 Oct 2002
Posts
5,600
Location
Surrey
tsj said:
thanks for that mate. it works :D

did you fix the code or just dump the code I gave you in to your program.

Stop and think about what you are doing, write a design, then write the code.

Thank about what functions need access to what data and only pass the data you need into them.

hint, the function that asks the user for a team name and creates the data storage structure doesn't need to know anything about how you are managing your collection of teams or how many teams there are in it.

now write some comments to detail what and why you are doing what you are doing. When I'm prototyping code with no detailed design I tent to put a comment in for every step I'll need code for and then write the code once I've got it clear in my head what needs to be done.

edit: pointer and arrays in C http://pw1.netcom.com/~tjensen/ptr/pointers.htm
 
Associate
Joined
17 Oct 2005
Posts
311
The major problem here is that the logic is completely broken. The loop in 'j' needs to only go up to i-1 (i.e. <i instead of <=i), so you're not checking against team 'i' which is the team you're actually adding. Secondly, you shouldn't actually add the team until you've finished your checking; currently you're adding it after the first go through the inner loop, and then you're taking it away again if you find a problem. Since you add it on the first go through the inner loop, you will always find it in your list of teams if you go through the inner loop more than once.

Your structure should really go more like:

for (i=0;i<NTeams;i++)
{
DO
Get Team Deatils;
Until Team Details are Valid (i.e. not a repeat of teams 0,..., i-1)
Add this team
}

it's actually slightly shorter to do it somewhat like the way you have (where you decrement i when you find a problem), but I would say that is poor style unless it's a very short loop. (Basically because knowing that "i" can be decremented somewhere in the loop is important, and in a long loop it's very easy to miss seeing it).
 

tsj

tsj

Permabanned
OP
Joined
7 May 2004
Posts
1,051
Location
United Kingdom
DaveF said:
The major problem here is that the logic is completely broken. The loop in 'j' needs to only go up to i-1 (i.e. <i instead of <=i), so you're not checking against team 'i' which is the team you're actually adding. Secondly, you shouldn't actually add the team until you've finished your checking; currently you're adding it after the first go through the inner loop, and then you're taking it away again if you find a problem. Since you add it on the first go through the inner loop, you will always find it in your list of teams if you go through the inner loop more than once.

Your structure should really go more like:

for (i=0;i<NTeams;i++)
{
DO
Get Team Deatils;
Until Team Details are Valid (i.e. not a repeat of teams 0,..., i-1)
Add this team
}

it's actually slightly shorter to do it somewhat like the way you have (where you decrement i when you find a problem), but I would say that is poor style unless it's a very short loop. (Basically because knowing that "i" can be decremented somewhere in the loop is important, and in a long loop it's very easy to miss seeing it).


DaveF i did as you said and it seems to work better for me :) Thanks

Would you just check over the code for errors for me? I cant see any myself but another person might be able to see something i cant.

Thanks

Code:
  for(i = 0; i < numofteams; i++)
  {
    char teamd[16];
        
    do 
    {
      
      printf("\nPlease enter team name:\n>");
      scanf("%s%c", teamd, &rtn);
      /** gets(teamd); **/
                
      ptr = teamd;
  
      for(int foo = 0 ; foo < strlen(teamd); foo++)
      {
        teamd[foo] = tolower(teamd[foo]);
      }
     
      printf("you entered %s ptr is %s", teamd, ptr);
     
      printf("i is %d", i);
     
      for(j = 0; j < i; j++)
      {
        match = strcmp(teamd, arrdetails[j].team);
        printf("\nmatch is %d", match);
        printf("\nteamd is %s and arrdetailsj is %s", teamd, arrdetails[j].team);
      }
 
      if(match == 0)
      {
        printf("\nSorry, this team already exists. Please try again!");
      }
                
    } while (match == 0);
  
    strcpy(arrdetails[i].team, teamd);
     arrdetails[i].played = 0;
     arrdetails[i].won = 0;
     arrdetails[i].lost = 0;
     arrdetails[i].draw = 0;
     arrdetails[i].points = 0;
     arrdetails[i].goalsfor = 0;
     arrdetails[i].goalsagainst = 0;
     arrdetails[i].goalsd = 0;
     arrdetails[i].team_id = num_teams;
     num_teams++;
    printf("\nwriting team num %d", i);
      
  }
 
Back
Top Bottom