0

What is wrong in this code? How do I find how many students have the same name?

How do I find out all the number of students who have same (Duplicate) name spelling (built in function cannot be used).

Input:

     Enter student name: Hasib
     Enter student name: Hasib
     Enter student name: Jhon

The output must be like this:

2 students have same name

Code:

#include <stdio.h>

struct student {
    char name[20];
};

int main() {
    struct student s[10];
    int i, j, count = 0;
    for (i = 0; i < 3; i++) {
        printf("Enter student name: ");
        gets(s[i].name);
    }
    for (i = 0; i < 3; i++) {
        for (j = i + 1; j < 3; j++) {
            if (s[i].name == s[j].name) {
                count++;
            }
        }
    }
    printf("\n%d students have same name\n\n", count);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 2
    Please properly format your code and tell us which inputs you used and what the result was. But the most basic problem here is that you use `==` to compare strings when you should be using `strcmp`. Also you algorithm does not do what you want. – Peter Sep 12 '20 at 13:40
  • @Peter i don't want to use strcmp. I want result without using strcmp –  Sep 12 '20 at 13:43
  • That makes no sense, please clarify your question, input, desired output, constraints, etc. – Peter Sep 12 '20 at 13:45
  • @Drhunter, `==` is not suited to compare strings in C. – anastaciu Sep 12 '20 at 13:45
  • 1
    Never *ever* use `gets`! It's so [dangerous](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) it has even been removed from the C standard. Use e.g. [`fgets`](https://en.cppreference.com/w/c/io/fgets) instead. – Some programmer dude Sep 12 '20 at 13:46
  • As for the comparison issue, `s[i].name == s[j].name` will only work when `i == j`. (which will never happen with your loops). Remember: Arrays decays to *pointers* to their first element. Now try to guess what you're really comparing. – Some programmer dude Sep 12 '20 at 13:47

2 Answers2

2

There are multiple problems:

  • C strings cannot be compared with == as you do. You just compare the pointers, not the contents of the arrays. You must include <string.h> and use:

      if (strcmp(s[i].name, s[j].name) == 0) {
          /* duplicate name */
      }
    
  • Also note that gets() must not be used as it may cause undefined behavior if the input is too long. As a matter of fact, attackers may take advantage of this flaw to execute arbitrary code. Use fgets() or scanf("%19s", s[i].name).

  • Why do you define the students array with 10 entries and only use 3 in the rest of the main() function?

Here is a modified version:

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

struct student {
    char name[20];
};

int main() {
    struct student s[10];
    int n, i, j, count;
    for (n = 0; n < 10; n++) {
        printf("Enter student name: ");
        if (scanf("%19s%*[^\n]", s[n].name) < 1)
            break;
    }
    count = 0;
    for (i = 0; i < n; i++) {
        for (j = i + 1; j < n; j++) {
            if (strcmp(s[i].name, s[j].name) == 0) {
                count++;
            }
        }
    }
    printf("\n%d students have same name\n\n", count);
    return 0;
}

EDIT: Your counting method is incorrect for more than 3 entries: if the 4 students have the same name, count will be incremented for pairs 0,1, 0,2, 0,3, 1,2, 1,3 and 2,3 hence 6 students with the same name (!).

Here is a corrected version that does not use strcmp() either:

#include <stdio.h>

struct student {
    char name[20];
};

int same_string(const char *s1, const char *s2) {
    while (*s1 == *s2) {
        if (*s1 == '\0')
            return 1;
        s1++;
        s2++;
    }
    return 0;
}

int main() {
    struct student s[10];
    int n, i, j, count;
    for (n = 0; n < 10; n++) {
        printf("Enter student name: ");
        if (scanf("%19s%*[^\n]", s[n].name) < 1)
            break;
    }
    count = 0;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            if (i != j && same_string(s[i].name, s[j].name)) {
                count++;
                break;
            }
        }
    }
    printf("\n%d students have same name\n\n", count);
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Thanks for your code. Is there any way to find duplicate without using strcmp() –  Sep 12 '20 at 16:26
  • @Drhunter Only by creating some actual string comparison code. What is the problem you have with `strcmp`? What do you have against it? You *do* understand what happens when using `==` to attempt to compare strings? – Some programmer dude Sep 12 '20 at 17:57
  • @Someprogrammerdude Actually someone ask me to do this without using strcmp. That is why i am asking for Is there any way to find duplicate without using strcmp() –  Sep 12 '20 at 18:12
  • @Drhunter Then you need to implement the string-comparison code yourself. You need to iterate over the two strings and compare them character by character. There are many examples and tutorials about this all over the Internet. – Some programmer dude Sep 12 '20 at 18:17
-1

Please use below code, == is not a working commands for strings, We can use Strcmp for the same.

  struct student
  {
   char name[20];
   };
 int main(){
   struct student s[10];
   int i,j=0,count,res;
   for(i=0; i<3; i++)
  {
     printf("Enter student name: ");
    gets(s[i].name);
    }
      for(i=0; i<3; i++)
   {
    for(j=i+1; j<3; j++)
    {

     if(strcmp(s[i].name, s[j].name)==0)
    {
        count++;
    }
    }
    } 
    printf("\n%d students have same name\n\n",count);
    }

Thanks

Anandha
  • 47
  • 10