how do i remove the similar word in strings? - c

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;
}

Related

split a string by a character without strtok in c

I need to write code that reads a string of characters such as jasf#fjaf#afsj to a single dimension string and then ask for a separation character (eg: #) so it will get an output in two dimensions and for every line, it will be the words between the separation character like:
jasf
fjaf
afsj
I tried:
#include <stdio.h>
#include <string.h>
void main {
int s, k, b;
printf("please enter a long string\n");
gets(longstring);
s = strlen(longstring);
printf("please choose seperationg charcter\n");
scanf("%c", &ch);
if ((ch < 'A') || ((ch > 'Z') && (ch < 'a')) || (ch > 'z')) {
for (k = 0; k < s; k++) {
for (b = 0; longstring[k] == ch; ++b) {
strcpy(mat[b], longstring);
}
}
puts(mat[b]);
}
Your code is incomplete: the function definition for main lacks its argument list, which is not optional in C, longstring is not defined, etc.
Futhermore, your method is too complicated: you do not need to test for letters if the goal is just to output one line for each part of the string between separators.
Here is a simple solution:
#include <stdio.h>
#include <string.h>
int main() {
char longstring[256];
int i, len;
char sep;
printf("please enter a long string\n");
if (fgets(longstring, sizeof longstring, stdin)) {
len = strlen(longstring);
printf("please choose a separationg character: ");
if (scanf("%c", &sep) != 1)
return 1;
for (i = 0; i < len; i++) {
if (longstring[i] == sep)
putchar('\n');
else
putchar(longstring[i]);
}
}
return 0;
}
since your code is not complete , let me add what is missing to achieve the task :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
char** str_split(char* a_str, const char a_delim)
{
char** result = 0;
size_t count = 0;
char* tmp = a_str;
char* last_comma = 0;
char delim[2];
delim[0] = a_delim;
delim[1] = 0;
/* Count how many elements will be extracted. */
while (*tmp)
{
if (a_delim == *tmp)
{
count++;
last_comma = tmp;
}
tmp++;
}
/* Add space for trailing token. */
count += last_comma < (a_str + strlen(a_str) - 1);
/* Add space for terminating null string so caller
knows where the list of returned strings ends. */
count++;
result = (char**) malloc(sizeof(char*) * count);
if (result)
{
size_t idx = 0;
char* token = strtok(a_str, delim);
while (token)
{
assert(idx < count);
*(result + idx++) = strdup(token);
token = strtok(0, delim);
}
assert(idx == count - 1);
*(result + idx) = 0;
}
return result;
}
int main()
{
char longstring[1024];
char** tokens;
char ch;
unsigned long s;
printf("please enter a long string\n");
gets(longstring);
s = strlen(longstring);
printf("please choose seperationg charcter\n");
scanf("%c", &ch);
if ((ch<'A') || ((ch>'Z') && (ch<'a')) || (ch>'z'))
{
tokens = str_split(longstring, ch);
if (tokens)
{
int i;
for (i = 0; *(tokens + i); i++)
{
printf("%s\n", *(tokens + i));
free(*(tokens + i));
}
printf("\n");
free(tokens);
}
}
return 0;
}

Splitting a string to an array of strings

I'm trying to split a sentence the user inputs to an array of words so I can later manipulate the words separately as strings.
The code is compiling but prints only garbage after the user input.
I tried debugging but don't see the problem. Can someone help me fix it?
#include <stdio.h>
#include <string.h>
int main() {
char str[1000];
int i = 0;
char rev[1000][1000];
int r = 0;
puts("Enter text:");
gets(str);
int k, length = 0;
printf_s("So the words are:\n");
while (str[i] != '\0') {
if (str[i] == ' ') {
k = i - length;
do {
rev[r][k] = (str[k]);
k++;
} while (str[k] != ' ');
printf(" ");
length = (-1);
r++;
} else
if (str[i + 1] == '\0') {
k = i - length;
do {
rev[r][k] = (str[k]);
k++;
} while (str[k] != '\0');
length = 0;
r++;
}
length++;
i++;
}
for (int r = 0; r < 1000; r++)
printf("%s ", rev[r]);
return 0;
}
fix like this
#include <stdio.h>
int main(void) {
char str[1000];
char rev[1000][1000];
puts("Enter text:");
fgets(str, sizeof str, stdin);//Use fgets instead of gets. It has already been abolished.
int r = 0;
int k = 0;
for(int i = 0; str[i] != '\0'; ++i){
if (str[i] == ' ' || str[i] == '\n'){//is delimiter
if(k != 0){
rev[r++][k] = '\0';//add null-terminator and increment rows
k = 0;//reset store position
}
} else {
rev[r][k++] = str[i];
}
}
if(k != 0)//Lastly there was no delimiter
rev[r++][k] = '\0';
puts("So the words are:");
for (int i = 0; i < r; i++){
printf("%s", rev[i]);
if(i < r - 2)
printf(", ");
else if(i == r - 2)
printf(" and ");
}
return 0;
}
Replace you declaration
char rev[1000][1000];
with
char * rev[1000]; // We will need pointers only
int i = 0; // Index to previous array
and all your code after
puts( "Enter text:" );
with this:
fgets( str, 998, stdin ); // Safe way; don't use gets(str)
const char delim[] = ",; "; // Possible delimiters - comma, semicolon, space
char *word;
/* Get the first word */
word = strtok( str, delim );
rev[i++] = word;
/* Get the next words */
while( word != NULL )
{
word = strtok( NULL, delim );
rev[i++] = word;
}
/* Testing */
for (int r = 0; r < i - 1; r++)
printf( "%s\n", rev[r] );
return 0
}
As you can see, all dirty work is done with the strtok() function ("string to tokens") which walks through other and other words ("tokens"), recognizing them as delimited by one or more characters from the string delim.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count_spaces(char *str)
{
if (str == NULL || strlen(str) <= 0)
return (0);
int i = 0, count = 0;
while (str[i])
{
if (str[i] == ' ')
count++;
i++;
}
return (count);
}
int count_char_from_pos(char *str, int pos)
{
if (str == NULL || strlen(str) <= 0)
return 0;
int i = pos, count = 0;
while (str[i] && str[i] != ' ')
{
count++;
i++;
}
return count;
}
char **get_words(char *str)
{
if (str == NULL || strlen(str) <= 0)
{
printf("Bad string inputed");
return NULL;
}
int i = 0, j = 0, k = 0;
char **dest;
if ((dest = malloc(sizeof(char*) * (count_spaces(str) + 1))) == NULL
|| (dest[0] = malloc(sizeof(char) * (count_char_from_pos(str, 0) + 1))) == NULL)
{
printf("Malloc failed\n");
return NULL;
}
while (str[i])
{
if (str[i] == ' ') {
dest[j++][k] = '\0';
if ((dest[j] = malloc(sizeof(char) * (count_char_from_pos(str, i) + 1))) == NULL)
{
printf("Malloc failed\n");
return NULL;
}
k = 0;
}
else {
dest[j][k++] = str[i];
}
i++;
}
dest[j][k] = 0;
dest[j + 1] = NULL;
return dest;
}
int main(void) {
char *line = NULL;
size_t n = 0;
getline(&line, &n, stdin);
printf("%s\n", line);
line[strlen(line) - 1] = 0;
printf("%s\n", line);
char **tab = get_words(line);
int i = 0;
while (tab[i])
{
printf("%s\n", tab[i++]);
}
}
here is a long but fully working example
get the user input
then send it to get_words function. It will get the number of words, the number of characters for each words, allocate everything in memory and writes chars then return it. You get a char ** and prints it just tested it it works
If you wish to split a string into an array of strings, you should consider the strtok function from #include <string.h>. The strtok function will the split the string on the given delimiter(s). For your case, it would the " ".
Using the strtok example from Tutorials Point:
#include <string.h>
#include <stdio.h>
int main(){
char str[80] = "This is - www.tutorialspoint.com - website";//The string you wish to split
const char s[] = "-";//The thing you want it to split from. But there is no need to this.
char *token;//Storing the string
/* get the first token */
token = strtok(str, s);//Split str one time using the delimiter s
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );//Print the string
token = strtok(NULL, s);//Split the string again using the delimiter
}
return(0);
}

C, comparing arrays, find a character,

So I am kinda new to coding, but what I want to do is write a string, write one character I wish not to be in the string if it occurs. I've tried using removedChar = getchar() instead of fgets(removedChar, 2, stdin); but then I can't do the != in the if statement.
I would really appreciate your help.
int main() {
char str[20], removedChar[2];
int i, n, j;
printf("ENTER A STRING:");
fgets(str, 20, stdin);
printf("ENTER WHAT CHAR YOU WISH TO REMOVE: ");
fgets(removedChar, 2, stdin);
n = strlen(str);
for (i = 0, j = 0; i < n; i++) {
if (strcmp(str, removedChar) == 0) {
str[j] = str[i];
j++;
}
if (str[i] == ' ') {
str[j] = str[i];
j++;
}
}
str[j] = '\0';
printf("string after removing character = %s", str);
system("pause");
return 0;
}
Firstly this line:
if (strcmp(str, removedChar) == 0)
is comparing if two strings are identical. Please see strcmp.
You need to instead compare character against characters, instead of equality of string against string.
Having said this, you can now just simply loop over the string, and use != to rule out matching characters, and update the string accordingly with a counter.
Additionally, it is always safe to check the return value of fgets, and also check that you havn't exceeded the buffer length.
This is the code that uses these ideas:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRSIZE 20
int
main(int argc, const char *argv[]) {
char str[STRSIZE];
int i, j, removedchar;
size_t slen;
printf("Enter a string: ");
if (fgets(str, STRSIZE, stdin) == NULL) {
printf("Error reading string\n");
return 1;
}
slen = strlen(str);
if (slen > 0) {
if (str[slen-1] == '\n') {
str[slen-1] = '\0';
} else {
printf("Error: Exceeded Buffer length of %d.\n", STRSIZE);
return 1;
}
}
if(!*str) {
printf("Error: No string entered.\n");
return 1;
}
printf("Enter what character you wish to remove: ");
removedchar = getchar();
if (removedchar == '\n') {
removedchar = ' ';
printf("No character was entered. Spaces will be removed if found\n");
}
j = 0;
for (i = 0; str[i] != '\0'; i++) {
if (str[i] != removedchar) {
str[j++] = str[i];
}
}
str[j] = '\0';
printf("Changed String = %s\n", str);
return 0;
}
You should use str[i] != removedChar[0] instead of using strcmp() which compares the full strings.
Also note that you should strip the newline character from the string read by fgets().
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char str[80], removedChar[80];
int i, n, j;
printf("ENTER A STRING: ");
if (!fgets(str, sizeof str, stdin))
return 1;
str[strcspn(str, "\n")] = '\0'; // strip the newline character if present
printf("ENTER WHAT CHAR YOU WISH TO REMOVE: ");
if (!fgets(removedChar, sizeof removedChar, stdin))
return 1;
for (i = 0, j = 0; str[i] != '\0'; i++) {
if (str[i] != removedChar[0]) {
str[j] = str[i];
j++;
}
}
str[j] = '\0';
printf("string after removing character = %s\n", str);
system("pause");
return 0;
}

Program that returns words that ends and starts with the same letter

I have problem with my alignement. This time I want my program to return words that ends and starts with the same letter. I've wrote something like this, but it seems to return random words.
#include <stdio.h>
#include <string.h>
void main()
{
char str[100];
int i, t, j, len;
printf("Enter a string : ");
scanf("%[^\n]s", str);
len = strlen(str);
str[len] = ' ';
for (t = 0, i = 0; i < strlen(str); i++)
{
if ((str[i] == ' ') && (str[i - 1] == str[0]))
{
for (j = t; j < i; j++)
printf("%c", str[j]);
t = i + 1;
printf("\n");
}
else
{
if (str[i] == ' ')
{
t = i + 1;
}
}
}
}
You can use strtok to split the strings from stdin, then apply a letter checker on each parsed word one at a time.
Something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXCHAR 100
int is_start_end(char *word);
void exit_if_null(void *ptr, const char *msg);
int
main(void) {
char str[MAXCHAR];
char *word;
char **all_words;
int words_size = 1, word_count = 0;
int i, found;
all_words = malloc(words_size * sizeof(*all_words));
exit_if_null(all_words, "initial Allocation");
printf("Enter words(enter empty line to terminate):\n");
while (fgets(str, MAXCHAR, stdin) != NULL && strlen(str) != 1) {
word = strtok(str, " \n");
while (word !=NULL) {
if (words_size == word_count) {
words_size *= 2;
all_words = realloc(all_words, words_size * sizeof(*all_words));
exit_if_null(all_words, "Reallocation");
}
all_words[word_count] = malloc(strlen(word)+1);
exit_if_null(all_words[word_count], "Initial Allocation");
strcpy(all_words[word_count], word);
word_count++;
word = strtok(NULL, " \n");
}
}
printf("Words that have equal first and last letters:\n");
found = 0;
for (i = 0; i < word_count; i++) {
if (is_start_end(all_words[i])) {
found = 1;
printf("%s\n", all_words[i]);
}
free(all_words[i]);
all_words[i] = NULL;
}
if (found == 0) {
printf("None Found\n");
}
free(all_words);
all_words = NULL;
return 0;
}
int
is_start_end(char *word) {
int len;
len = strlen(word);
if ((len == 1) || (tolower(word[0]) == tolower(word[len-1]))) {
return 1;
}
return 0;
}
void
exit_if_null(void *ptr, const char *msg) {
if (!ptr) {
printf("Unexpected null pointer: %s\n", msg);
exit(EXIT_FAILURE);
}
}
This line removes the null terminator of the string:
len = strlen(str);
str[len] = ' ';
thus the string no longer exists, what is left is just an ordinary array of characters.
The next call to strlen, in the body of the for loop, will cause undefined behavior.

Counting substrings in C

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");

Resources