A friend of mine needed help counting the occurrences of a substring in a string, and I came up with the following code. Does anyone know a better method to do this?
#include "stdio.h"
#include "string.h"
int main(int argc, char *argv[])
{
char str1[50], str2[50];
int i, j, l1, l2, match, count;
printf("String 1:\n");
gets(str2);
printf("String 2:\n");
gets(str1);
l1 = strlen(str1);
l2 = strlen(str2);
count = 0;
for(i = 0; i < l1; i++)
{
match = 0;
for(j = 0; j < l2; j++)
{
if(str1[i + j] == str2[j])
{
match++;
}
}
if(match == l2)
{
count++;
}
}
printf("Substrings: %d\n", count);
}
how about this: (using the strstr function, reference here)
int count = 0;
char str1[50], str2[50];
char* tmp = str1;
int count;
printf("String 1:\n");
gets(str2);
printf("String 2:\n");
gets(str1);
while(*tmp != '\0' && (tmp = strstr(tmp, str2))) {
++count;
++tmp;
}
Please do not use or encourage the use of gets. Beyond the fact that it will introduce a point of failure in your code, it has been deprecated as of C99 and will be gone completely from C1X.
As others have said, strstr is your friend here:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s1[50], s2[50];
char *p;
size_t count = 0;
size_t len1;
printf("Gimme a string: ");
fflush(stdout);
fgets(s1, sizeof s1, stdin);
p = strchr(s1, '\n'); // get rid of the trailing newline
if (p)
*p = 0;
printf("Gimme another string: ");
fflush(stdout);
fgets(s2, sizeof s2, stdin);
p = strchr(s2, '\n'); // get rid of the trailing newline
if (p)
*p = 0;
p = s2;
len1 = strlen(s1);
while ((p = strstr(p, s1)) != NULL && p != s1)
{
count++;
p += len1;
}
printf("Found %lu occurrences of %s in %s\n", count, s1, s2);
return 0;
}
You might want to take a look at the strstr function (if you're not already familiar with it).
int main()
{
char *str = "This is demo";
char *sub = "is";
int i,j,count;
i=j=count=0;
while(str[i]!='\0')
{
if (str[i] == sub[j] && str[i+1] == sub[j+1])
{
count++;
}
i++;
}
cout<<count;
return 0;
}
Above code works but this is static.
You can use QString in QT library
QString t = "yourstring";
t.count("yoursubstring");
Related
I was making a split function in C to use its return value in some programs. But when I checked its value using printf, I discovered that there are some errors but I was unable to fix them myself. I fixed most of the errors I could.
The code I wrote is:
#include <stdio.h>
#include <string.h>
char **split(char *token, char *delimiter, int *a[], int *size_of_a) {
int i = 0;
char **final_result;
char *str = strtok(token, delimiter);
while (str != NULL) {
*a[i] = strlen(str); //maybe one of the errors but I don't know how to fix it
//even after removing a[i] by backslash and changing it in loop and main, there is still no output received in main
getch();
for (int j = 0; j < *a[i]; j++) {
final_result[i][j] = str[j];
}
str = strtok(NULL, delimiter);
i++;
}
*size_of_a = i;
return final_result;
}
int main() {
char *parameter_1;
char *parameter_2;
int *size_1;
int size_2;
printf("Enter the token: ");
scanf("%s", ¶meter_1);
printf("\nEnter the delimiter: ");
scanf("%s", ¶meter_2);
char **result_2 = split(parameter_1, parameter_2, &size_1, &size_2);
printf("\nThe result is:");
for (int x = 0; x < size_2; x++) {
printf('\n');
for (int y = 0; y < size_1[x]; y++) {
printf("%c", result_2[x][y]);
}
}
getch();
return 0;
}
How can I fix the output error?
There are multiple problems in the code:
You do not allocate space for the array of pointers: final_result is uninitialized, storing anything via dereferencing it has undefined behavior, most likely a segmentation fault.
You should use strcpn() and strspn() to compute the number of tokens, allocate the array with or without an extra slot for a NULL terminator and perform a second phase splitting the tokens and storing the pointers to the array. You might want to store copies of the tokens to avoid modifying the original string that may be constant or go out of scope.
printf('\n'); is invalid: you must pass a string, not a character constant.
scanf("%s", ¶meter_1); also has undefined behavior: you pass the address of a pointer instead of a pointer to an array of char.
Here is a modified version:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _MSC_VER
// define POSIX function strndup if not available
char *strndup(const char *s, size_t n) {
size_t len;
for (len = 0; len < n && s[len]; len++)
continue;
char *ptr = malloc(len + 1);
if (ptr) {
memcpy(ptr, s, len);
ptr[len] = '\0';
}
return ptr;
}
#endif
char **split(const char *str, const char *delimiters, int **a, int *size_of_a) {
int i, count, len;
char **final_result;
const char *p;
// phase 1: count the number of tokens
p = str + strspn(str, delimiters);
for (count = 0; *p; count++) {
p += strcspn(p, delimiters);
p += strspn(p, delimiters);
}
// phase 2: allocate the arrays
final_result = calloc(sizeof(*final_result), count + 1);
if (a) {
*a = calloc(sizeof(**a), count);
}
if (size_of_a) {
*size_of_a = count;
}
// phase 3: copy the tokens
p = str;
for (i = 0; i < count; i++) {
p += strspn(p, delimiters); // skip the delimiters
len = strcspn(p, delimiters); // count the token length
if (a) {
(*a)[i] = len;
}
final_result[i] = strndup(p, len); // duplicate the token
p += len;
}
final_result[count] = 0;
return final_result;
}
// read and discard the rest of the user input line
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
int main() {
char buf[256];
char delimiters[20];
printf("Enter the string: ");
if (scanf("%255[^\n]", buf) != 1)
return 1;
flush_input();
printf("\nEnter the delimiters: ");
if (scanf("%19[^\n]", delimiters) != 1)
return 1;
flush_input();
int *sizes;
int count;
char **array = split(buf, delimiters, &sizes, &count);
printf("\nThe result is:\n");
for (int x = 0; x < count; x++) {
for (int y = 0; y < sizes[x]; y++) {
putchar(array[x][y]);
}
printf("\n");
}
getchar();
return 0;
}
I'm learning C now
I need to make a program that remove char that I'll input from string. I've seen an algorithm and I write this code
#define MAX_LEN 200
int main()
{
char str[MAX_LEN];
char rem;
int i = 0;
printf("Enter the setence:");
gets(str);
printf("\nEnter the char to remove");
rem = getchar();
char* pDest = str;
char* pS= str;
printf("sent:\n%s", str);
while (str[i]!='\0'){
if (*pDest != rem) {
*pDest = *pS;
pDest++;
pS++;
}
else if (*pDest == rem) {
pS++;
}
i++;
}
*pDest = '\0';
while (str[i] != '\0') {
printf("number%d", i);
putchar(str[i]);
printf("\n");
i++;
}
}
But it returns nothing, like the value str gets, i think \0 and retuns nothing.
May you help me to find the problem?
Use functions!!
If dest is NULL then this function will modify the string str otherwise, it will place the string with removed ch in dest.
It returns reference to the string with removed character.
char *removeChar(char *dest, char *str, const char ch)
{
char *head = dest ? dest : str, *tail = str;
if(str)
{
while(*tail)
{
if(*tail == ch) tail++;
else *head++ = *tail++;
}
*head = 0;
}
return dest ? dest : str;
}
int main(void)
{
char str[] = "ssHeslsslsos sWossrlssd!ss";
printf("Removal of 's' : `%s`\n", removeChar(NULL, str, 's'));
}
It would be easier to use array style indexing to go through the string. For example use str[i] = str[i + 1] instead of *pstr = *other_pstr. I leave this incomplete method, since this looks like homework.
int main()
{
char str[] = "0123456789";
char ch = '3';
for (int i = 0, len = strlen(str); i < len; i++)
if (str[i] == ch)
{
for (int k = i; k < len; k++)
{
//Todo: shift the characters to left
//Hint, it's one line
}
len--;
}
printf("%s\n", str);
return 0;
}
I just added new char array char dest[MAX_LEN] that store string with deleted symbols:
#define MAX_LEN 200
int main()
{
char str[MAX_LEN];
char rem;
int i = 0;
printf("Enter the setence:");
gets(str);
printf("\nEnter the char to remove");
rem = getchar();
char dest[MAX_LEN] = "\0";
char* pDest = dest;
char* pS = str;
printf("sent:\n%s", str);
while (str[i]!='\0')
{
if (*pS != rem)
{
*pDest = *pS;
pDest++;
pS++;
}
else if (*pS == rem)
{
pS++;
}
i++;
}
i = 0;
printf("\nres:\n %s \n", dest);
while (dest[i] != '\0') {
printf("number%d", i);
putchar(dest[i]);
printf("\n");
i++;
}
}
I have program to remove the similar words from string but this program only removing at once word not a repeating words.
For example input:
sabunkerasmaskera kera
and should an output:
sabunmas
This my code:
#include <stdio.h>
#include <string.h>
void remove(char x[100], char y[100][100], char words[100]) {
int i = 0, j = 0, k = 0;
for (i = 0; x[i] != '\0'; i++) {
if (x[i] == ' ') {
y[k][j] = '\0';
k++;
j = 0;
} else {
y[k][j] = x[i];
j++;
}
}
y[k][j] = '\0';
j = 0;
for (i = 0; i < k + 1; i++) {
if (strcmp(y[i], kata) == 0) {
y[i][j] = '\0';
}
}
j = 0;
for (i = 0; i < k + 1; i++) {
if (y[i][j] == '\0')
continue;
else
printf("%s ", y[i]);
}
printf ("\n");
}
int main() {
char x[100], y[100][100], kata[100];
printf ("Enter word:\n");
gets(x);
printf("Enter word to remove:\n");
gets(words);
remove(x, y, words);
return 0;
}
My program output its:
sabunkerasmaskerara
and that should not be the case. Maybe I need your opinion to fixed this program and also I need help to make it better.
Your solution does not work because it uses strcmp to compare the string portions, which only works if the substring is at the end of the string, as this makes it null-terminated.
You should instead use strstr to locate the matches and use memmove to shift the string contents.
There are other issues in your code:
do not use gets()
y is unnecessary for this task.
words is not defined
Here is a modified version:
#include <stdio.h>
#include <string.h>
char *remove_all(char *str, const char *word) {
size_t len = strlen(word);
if (len != 0) {
char *p = str;
while ((p = strstr(p, word)) != NULL) {
memmove(p, p + len, strlen(p + len) + 1);
}
}
return str;
}
int main() {
char str[100], word[100];
printf ("Enter string:\n");
if (!fgets(str, sizeof str, stdin))
return 1;
printf("Enter word to remove:\n");
if (!fgets(word, sizeof word, stdin))
return 1;
word[strcspn(word, "\n")] = '\0'; // strip the trailing newline if any
remove_all(str, word);
fputs(str, stdout);
return 0;
}
Im trying to make the program remove a character from a string that the user is putting in but i get an error inside the loop. (side question: is adding a character inside the string the "same" code with some small changes?)
PS New to programming...
Is this what you are trying to achieve?
Changes:
getchar() and fgets() to scanf()
added strlen() to get length of string
added lenght of input string to printf
added zero init of strings
Note: After each input with scanf() you have to press enter.
int main()
{
char str[100] = { 0 };
char ch[5] = { 0 };
int k, j;
printf("Write text:\n");
scanf("%s", str);
printf("Input was: %s\nLength: %d\n", str, strlen(str));
printf("Write a character that should be removed\n");
scanf("%s", ch);
for (k = 0, j = 0; k < strlen(str); k++)
{
if (str[k] != ch[0]) {
str[j] = str[k];
j++;
}
}
str[j] = '\0';
printf("String after removing a character: %s", str);
}
Problems with your code:
str[k] != ch would be a valid test if ch were indeed a character and not an array of characters of length 5. This is going to compare the character value of str[k] with the address &ch[0].
k < str would be a valid comparison if k was a char * pointer that was initialized at &str[0], not an int loop index starting at 0.
Corrected code:
int main(void)
{
char str[100];
char ch[5];
int k, j;
printf("Write text:\n");
//getchar();
fgets(str, 100, stdin);
printf("Input was: %s\n", str);
printf("Write a character that should be removed\n");
//getchar();
fgets(ch, 5, stdin);
for (k = 0, j = 0; k < strlen(str); k++)
{
if (str[k] != ch[0])
{
str[j] = str[k];
j++;
}
}
str[j] = '\0';
printf("String after removing a character = %s", str);
return 0;
}
Here you have two implementations. Both remove all occurrences of the char ch from the string str
First algorithm is much faster. The second slower but easy to understand
#include <stdio.h>
#include <string.h>
char *removechar(char *str, int ch)
{
char *cptr = str, *readptr = str;
while(*readptr)
{
if(*readptr == ch)
{
readptr++;
}
else
{
*cptr++ = *readptr++;
}
}
*cptr = 0;
return str;
}
char *removechar(char *str, int ch)
{
char *cpos = str;
while((cpos = strchr(cpos, ch)))
{
strcpy(cpos, cpos + 1);
}
return str;
}
int main()
{
char s[] = "Hello World";
printf("%s\n", removechar(s, 'd'));
printf("%s\n", removechar(s, 'l'));
return 0;
}
Is this what you want to achieve?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
char str[100],c;
printf("Write text:\n");
fgets(str,100,stdin);
printf("Input was: %s\n", str);
printf("Write a character that should be removed\n");
c=getchar();
for(int k=0;k<strlen(str);k++){
if(str[k]==c){
for(int j=k;j<strlen(str);j++){
str[j]=str[j+1];
}
}
}
printf("String after removing a character = %s", str);
return 0;
}
#include <stdio.h>
#include <string.h>
#define SIZE 40
int main(void)
{
char buffer1[SIZE] = "computer program";
char *ptr;
int ch = 'p', j = 0, i;
for (i = 0; i<strlen(buffer1); i++)
{
ptr = strchr(buffer1[i], ch);
if (ptr != 0) j++;
printf(" %d ", j);
}
}
I want to count how many times a character occurs in a string.
In my program I chose the character 'p'.
I know Pascal, I am learning C now. In pascal is a function called Pos(x,y) which is searching for x in y. Is something familiar to this? I think what I used here is not.
The function signature of strchr is
char *strchr(const char *s, int c);
You need to pass a char* but you have passed a char. This is wrong.
You have used the strlen in loop - making it inefficient. Just calculate the length of the string once and then iterate over it.
char *t = buffer;
while(t!= NULL)
{
t = strchr(t, ch);
if( t ) {
t++;
occurences++;
}
}
And without using standard library functions you can simply loop over the char array.
size_t len = strlen(buffer);
for(size_t i = 0; i < len; i++){
if( ch == buffer[i]) occurences++;
}
Or alternatively without using strlen
char *p = buffer;
while(*p){
if( *p == ch ){
occurences++;
}
p++;
}
Or
for(char *p = buffer; *p; occurences += *p++ == ch);
Try this example :
int main()
{
char buffer1[1000] = "computer program";
char ch = 'p';
int i, frequency = 0;
for(i = 0; buffer1[i] != '\0'; ++i)
{
if(ch == buffer1[i])
++frequency;
}
printf("Frequency of %c = %d", ch, frequency);
return 0;
}