0

The problem itself is simple. I have to count the number of occurence of s2 in s1. And length of s2 is always 2. I tried to implement it with C, but it did not work even though i know the logic is correct. So i tried the same logic in pyhton and it works perfectly. Can someone explain why? Or did i do anything wrong in C. I given both codes below.

C

#include<stdio.h>
#include<string.h>
int main()
{
char s1[100],s2[2];
int count = 0;
gets(s1);
gets(s2);
for(int i=0;i<strlen(s1);i++)
{
    if(s1[i] == s2[0] && s1[i+1] == s2[1])
    {
        count++;
    }
}
printf("%d",count);
return 0;
}

Python

s1 = input()
s2 = input()
count = 0
for i in range(0,len(s1)):
    if(s1[i] == s2[0] and s1[i+1] == s2[1]):
        count = count+1
print(count)
Sricharan
  • 3
  • 2
  • 1
    You should never ever use `gets`. It is considered dangerous and was obsoleted in the standard. Check the manual for `fgets` instead. Your second string `s2` can only hold a string of length 1. The second byte is required for the terminating 0 byte. If you enter more than 1 character, you will have a buffer overrun causing undefined behaviour. – Gerhardh Nov 29 '21 at 17:30
  • 1
    This isn't what is causing the issue, but your for loop could access data from outside the array on its last iteration – Erik McKelvey Nov 29 '21 at 17:30
  • Does this answer your question? [find the count of substring in string](https://stackoverflow.com/questions/9052490/find-the-count-of-substring-in-string) – Robert Harvey Nov 29 '21 at 17:31
  • `s1[i+1]` This will probably not access the array out of bounds but it will hit the 0 byte if `i == strlen(s1)-1` That is not what you want. – Gerhardh Nov 29 '21 at 17:31
  • Thanks @Gerhardh , it works now. So the size of s2 was the problem. I never thought that '\0' would also require space within the string. : ) – Sricharan Nov 29 '21 at 17:38
  • @Gerhardh, Yep, `scanf ("%s", s1)` is safer. – Rafaelplayerxd YT Nov 29 '21 at 17:46
  • @RafaelplayerxdYT that would rather be `"%1s"` or with fixed buffer size `"%2s"`. Otherwise it is barely better than `gets`. – Gerhardh Nov 29 '21 at 17:50
  • Sure, I just generalized it for simplicity – Rafaelplayerxd YT Nov 29 '21 at 17:51
  • @RafaelplayerxdYT I would suggest to avoid such simplifications when the OP seems to be a beginner. Especially if that exact detail was what caused the OP's problem. – Gerhardh Nov 29 '21 at 17:53

2 Answers2

0

Your python code is actually incorrect, it would raise an IndexError if the last character of s1 matches the first of s2.

You have to stop iterating on the second to last character of s1.

Here is a generic solution working for any length of s2:

s1 = 'abaccabaabaccca'
s2 = 'aba'
count = 0
for i in range(len(s1)-len(s2)+1):
    if s2 == s1[i:i+len(s2)]:
        count += 1
print(count)

output: 3

mozway
  • 194,879
  • 13
  • 39
  • 75
0

First, as others have pointed out, you do not want to use gets(), try using fgets(). Otherwise, your logic is correct but when you read in the input, the new line character will be included in the string.

If you were to input test and es, your strings will contain test\n and es\n (with both respectively containing the null terminating byte \0). Then leads to you searching the string test\n for the substring es\n which it will not find. So you must first remove the new line character from, at least, the substring you want to search for which you can do with strcspn() to give you es.

Once the trailing newline (\n) has been replaced with a null terminating byte. You can search the string for occurances.

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

int main() {
    char s1[100], s2[4];
    int count = 0;
    fgets(s1, 99, stdin);
    fgets(s2, 3, stdin);
    s1[strcspn(s1, "\n")] = '\0';
    s2[strcspn(s2, "\n")] = '\0';

    for(int i=0;i < strlen(s1) - 1;i++) {
        if(s1[i] == s2[0] && s1[i+1] == s2[1]) {
            count++;
        }
    }

    printf("%d\n",count);
    return 0;
}
codyne
  • 552
  • 1
  • 9
  • Then you should also include that in your explanation why this caused the issue. `gets` was only part of it. – Gerhardh Nov 29 '21 at 17:54
  • @Gerhardh no need for 4 size to read 2 chars if you don't care about the newline. `fgets` will always add the NUL terminator, overwriting the newline if it's at `sizeof(buf) - 1`: https://godbolt.org/z/KdT6xq31G – yano Nov 29 '21 at 18:00
  • @yano you are right. I forgot about that. – Gerhardh Nov 29 '21 at 18:55