String manipulation (variable output with the same input) - c

Maybe some property is passing unnoticed to me, but when 'i' is 1 it just freeze. When i input whatever string, 'j' variable goes to 700 or 2000 in different executions. The code goal is to output repetitive letters if you input "cheese" the output should be "eee". What am i doing wrong?
#include <stdio.h>
char * repeticoes(char *s) {
int index = 0;
for (int i = 0;( s[i] != '\0'); i++) //problem starts when i is > 0
{
for (int j = 0; ( s[j] != '\0'); j++)
{
if (s[i] == s[j])
{
printf("%c == %c\ni %d j %d\n", s[i], s[j],i,j);
s[index++] = s[i];
}
else
{
printf("not happening %c != %c\ni %d j %d\n", s[i],s[j],i,j);
}
}
}
s[++index] = '\0';
return s;
}
main() {
char input[21];
printf("str 1\n");
fgets(input, 20, stdin);
repeticoes(input);
printf("duplicated letters %s\n", input);
}

You need to start the inner loop at the next character after the one being processed in the outer loop, otherwise you'll process the same pair of characters twice, as well as testing a character against itself when i == j.
You should also break out of the inner loop as soon as you find a match. You'll find later matches in a future iteration of the outer loop. Otherwise you'll process the same pair twice again.
And you shouldn't increment index before assigning the null character after the loop. It was already incremented when adding the repetition.
#include <stdio.h>
char * repeticoes(char *s) {
int index = 0;
for (int i = 0;( s[i] != '\0'); i++) //problem starts when i is > 0
{
for (int j = i+1; ( s[j] != '\0'); j++)
{
if (s[i] == s[j])
{
printf("%c == %c\ni %d j %d\n", s[i], s[j],i,j);
s[index++] = s[i];
break;
}
else
{
printf("not happening %c != %c\ni %d j %d\n", s[i],s[j],i,j);
}
}
}
s[index] = '\0';
return s;
}
int main() {
char input[21];
printf("str 1\n");
fgets(input, 20, stdin);
repeticoes(input);
printf("duplicated letters %s\n", input);
}

With an array of letters to count and an array of counts. Once the letters have been counted, loop through the input again and set the letters that have a count greater than one.
#include <stdio.h>
void repeticoes ( char *s) {
char tocount[] = "abcdefghijklmnopqrstuvwxyz";
size_t len = sizeof tocount;
size_t index = 0;
int count[len];
for (int j = 0; j < len; j++) {
count[j] = 0;
}
for (int i = 0;( s[i] != '\0'); i++) {
for (int j = 0; j < len; j++) {
if ( s[i] == tocount[j]) {
count[j]++;
}
}
}
for (int i = 0;( s[i] != '\0'); i++) {
for (int j = 0; j < len; j++) {
if ( s[i] == tocount[j] && 1 < count[j]) {
s[index] = s[i];
index++;
}
}
}
s[index] = '\0';
}
int main ( void) {
char input[21];
printf("str 1\n");
fgets(input, 20, stdin);
repeticoes(input);
printf("duplicated letters %s\n", input);
return 0;
}

Related

C - How to input and insert a string into an array of strings?

I want to insert string to the array until I type "ok". Why I am getting just "ok" and original array at the output?
int main(void)
{
char b[20];
char* str[10] = { "1","2" };
int i = 2;
while (1) {
gets(b);
if (strcmp(b, "ok") == 0) break;
str[i] = b;
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
return 0;
}
You need to allocate a string on each iteration:
int main(void)
{
char* b;
char* str[10] = { "1","2" };
int i = 2;
while (1) {
b = malloc(20);
gets(b);
if (strcmp(b, "ok") == 0) break;
str[i] = b;
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
// free allocated strings
while (i > 2)
free(str[--i]);
return 0;
}
They all point to b, which gets overwritten in each iteration.
You need to create a copy of the string when you assign it:
str[i] = strdup(b);
You also may consider using fgets instead of gets; however, you will need to remove the newline:
size_t size;
fgets(str, 20, stdin);
size = strlen(str);
if(str[size-1] == '\n')
str[size-1] = '\0';
Also, print a newline at the end of your program, so it won't interfere with the shell:
putchar('\n');
Full code:
int main(void)
{
char b[20];
char* str[10] = { "1","2" };
int i = 2;
while (1) {
size_t size;
fgets(str, 20, stdin);
size = strlen(str);
if(str[size-1] == '\n')
str[size-1] = '\0';
if (strcmp(b, "ok") == 0)
break;
str[i] = strdup(b);
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
putchar('\n');
return 0;
}
You need to make a copy of the input string, then save a pointer to the copy of the input string in your array. Something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char b[20];
char *str[10] = { "1","2" };
int i = 2;
char *p;
size_t lenb;
for(i = 2 ; i < 10 ; ++i)
{
fgets(b, sizeof(b), stdin);
lenb = strlen(b);
if(lenb > 0 && *(b+lenb-1) == '\n')
{
*(b+lenb-1) = '\0'; /* overwrite the trailing \n */
lenb = strlen(b);
}
if (strcmp(b, "ok") == 0)
break;
p = malloc(lenb+1);
strcpy(p, b);
str[i] = p;
}
for (int j = 0; j < i; j++)
printf("%s\n", str[j]);
return 0;
}

trying to use strcmp in if function for counting anagrams in a sentence

hii guys i need a serious help
i m trying to write a code for finding anagrams in input sentence
but when the if function is getting strcmp it stops and its not accepting the condition. any body know why is that happening
Basically my code supposed to do two things one is taking a sentence from the user and making the words appear in the Backwoods order two Its need to take the whole sentence and look for anagrams ( anagram means that there is the same letters but in a different order for example this and shit are anagrams) thank you very much for your help :)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
int index_for_word_start, words_num = 1,amount_of_letters;
int i, j, k;
char inpot_Sentence[1001], temp_letters;
char **words,**sorting_words;
int counter = 0,counter_max_for_anegram=0;
printf_s("Please enter the sentence, and then press Enter:\n");
gets(inpot_Sentence);
/////////////////////////////makeing the sentence backwards///////////////////////
for (i = 0; inpot_Sentence[i] != '\0'; i++) //loop for counting how many words(it will be use to know how many pointer we need)
{
if (inpot_Sentence[i] == ' ')
{
words_num++;
}
}
words = (char **)malloc(sizeof(char *)*words_num); //malloc for pointers that point on the pointer of the word
index_for_word_start = 0;
for (j = 0; j<words_num; j++)
{
for (i = index_for_word_start; inpot_Sentence[i] != ' '; i++)
{
if (!inpot_Sentence[i]) //if the user didnt put any word(break)
{
break;
}
}
words[j] = (char*)malloc(sizeof(char)*(i - index_for_word_start + 1)); //malloc of pointers that point on each word
strncpy_s(words[j], i - index_for_word_start+1, &inpot_Sentence[index_for_word_start], i - index_for_word_start); //copy the words from inpot sentence to array
words[j][i - index_for_word_start] = 0; //puts '\0' after the word copy ends
index_for_word_start = i + 1;
}
printf_s("\nThe reverse sentence is:\n");
for (i = words_num - 1; i >= 0; i--) //print the words in backwards Sequence
{
printf("%s ", words[i]);
}
putchar('\n');
i = 0;
/////////////////////anegrams check///////////////////////
for (j = 0; j < words_num; j++) //loops that Arrange the array by haski value
{
amount_of_letters = strlen(words[j]);
for ( i = 0; i < amount_of_letters; i++)
{
for (k = 0; k < amount_of_letters; k++)
{
if (words[j][i]<words[j][k])
{
temp_letters = words[j][i];
words[j][i] = words[j][k];
words[j][k] = temp_letters;
}
}
}
printf_s("this is words %s\n", words[j]);
}i = 0;
for ( j = 0; j < words_num-1; j++)
{
for ( i = 0; i < words_num-1; i++)
{
if (!strcmp(words[j],words[i]) && (i!=j) && (strcmp(words[j],"\0")))
{
counter++;
words[i] = 0;
}
else
{
break;
}
}
if (counter>counter_max_for_anegram)
{
counter_max_for_anegram = counter;
}
counter = 0;
}
printf_s("%d\n", counter_max_for_anegram);
for ( j = 0; j < words_num; j++)
{
free(words[j]);
}
free(words);
}
#include <stdio.h>
#include <string.h>
int check_anagram(char[],char[]);
int main()
{
char a[100],b[100];
int flag;
puts("Enter the first string");
fgets(a,100,stdin);
a[strcspn(a, "\r\n")] = '\0';
puts("Enter the second string");
fgets(b,100,stdin);
b[strcspn(b, "\r\n")] = '\0';
flag=check_anagram(a,b);
if(flag)
printf("%s and %s are anagrams",a,b);
else
printf("%s and %s are not anagrams",a,b);
}
int check_anagram(char a[], char b[])
{
int first[26]={0},second[26]={0},c=0;
while(a[c]!='\0')
{
first[a[c]-'a']++;
c++;
}
c=0;
while(b[c]!='\0')
{
second[b[c]-'a']++;
c++;
}
for(c=0;c<26;c++)
{
if(first[c]!=second[c])
return 0;
}
return 1;
}

Sorting word occurrence in string C programming

I have been stuck on this for a while now. I wrote my program to count word occurrence in an inputted string by the user as well to sort the words alphabetically. My issue is my program runs perfectly only if there are spaces in between the words inputted. For example, if I input "to to," my program will count those two words as two different words due to the comma rather than counting it as one word in "to" as I would like it to. It is that issue for all of my delimiters in the array const char delim[]. How can I fix this issue in my program? I really appreciate any help! My code is down below:
Edit: I took Bob's suggestion to use strchr() and it worked! My only issue is my program outputs the count for delimiters now. I was thinking of possibly writing an if statement when comparing words[i] with words[j] to see if they have the same value. Is that the best approach to it?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
const char delim[] = ", . - !*()&^%$##<> ? []{}\\ / \"";
#define SIZE 1000
int main(){
char string[SIZE], words[SIZE][SIZE], temp[SIZE];
int a = 0, i = 0, j = 0, k = 0, n = 0, count;
int c = 0, cnt[26] = { 0 };
int word = 0;
int x;
printf("Enter your input string:");
fgets(string, SIZE, stdin);
string[strlen(string) - 1] = '\0';
lower(string);
/*extracting each and every string and copying to a different place */
while (string[i] != '\0'){
if (strchr(", . - !*()&^%$##<> ? []{}\\ / \"", string[i]) != NULL){
words[j][k] = '\0';
k = 0;
j++;
}else {
words[j][k++] = string[i];
}
i++;
}
words[j][k] = '\0';
n = j;
printf("Number of occurences of each word unsorted:\n");
i = 0;
/* find the frequency of each word and print the results */
while (i <= n) {
count = 1;
if (i != n) {
for (j = i + 1; j <= n; j++) {
if (strcmp(words[i], words[j]) == 0) {
count++;
for (a = j; a <= n; a++)
strcpy(words[a], words[a + 1]);
n--;
}
}//for
}
//word == strtok(string, delim);
/* count - indicates the frequecy of word[i] */
printf("%s\t%d\n", words[i], count);
i = i + 1;
}//while
printf("Alphabetical Order:\n");
/* sort the words in the given string */
for (i = 0; i < n; i++){
strcpy(temp, words[i]);
for (j = i + 1; j <= n; j++){
if (strcmp(words[i], words[j]) > 0){
strcpy(temp, words[j]);
strcpy(words[j], words[i]);
strcpy(words[i], temp);
}
} //inner for
} //outer for
i = 0;
while (i <= n) {
count = 1;
if (i != n) {
for (j = i + 1; j <= n; j++) {
if (strcmp(words[i], words[j]) == 0) {
count++;
}
}
}
printf("%s\n", words[i]);
i = i + count;
}
}
Strip every word of that delimeter before comparing. Actually you don't even need a list of delimeters because words are 'alpha' other than that it's a delimeter.
Please try this, it works, it is an extract of your own code, a little bit modified, it will give you the count, then you have to write the rest, have fun.
#include <string.h>
#define YES 1
#define NO 0
int main( )
{
char string[1000];
int i = 0;
int j = 0;
int is_this_a_word = 0;
strcpy( string, " to or not ,tobe" );
while ( string[i++] != '\0' )
{
if ( strchr( ", . - !*()&^%$##<> ? []{}\\ / \"", string[i] ) != NULL )
{
is_this_a_word = NO;
}
else
{
if ( ! is_this_a_word )
{
is_this_a_word = YES;
j++;
}
}
}
printf( "I counted %d words", j );
getchar( );
}

Messing with Character Arrays in C

Can someone advise why the loop in the main dies after the fifth iteration never completing
it's intended goal of reducing the character array down to 1 final element? I've gotten it this
far and am completely consumed as their should be 11 iterations as returned by the call
size_t strlen( char const *str )
{
int length = 0;
while (*str++ !='\0')
{
length += 1;
}
return length;
}
void abracadabra( char *word )
{
int i, c;
int len = strlen(word)-1;
for (i = 0; i <= len; i++)
{
putchar(*word);
putchar(' ');
*(word++);
}
}
int main()
{
char word[250];
int i, j;
printf ("enter your word:\n");
scanf ("%[^\n]s", &word);
for (i = 0; i <= strlen(word)-1; i++)
{
abracadabra(word);
putchar('\0');
printf("\n");
for (j = 0; j <= i; j++)
{
putchar('\0');
}
word[strlen(word) - 1] = '\0';
}
word[strlen(word)-1] = '\0';
printf("\n");
system("pause");
return 0;
}
Each time you execute the outer for loop in main the size of the string decreases by 1. The counter i is also increasing by 1 each time. This causes you to run the loop half of the times that you intend to.
int size = strlen(word);
for (i = 0; i < size; i++) {
\\same inner code
}
Subbing the above code for the outer for loop in main resolves the issue.
The is mistake in using the variable i and strlen in for loop. i is keep increasing and word length is decreasing. So in the mid, loop is terminated due to i>strlen (word)
int main()
{
char word[250];
int i, j;
printf ("enter your word:\n");
scanf ("%[^\n]s", &word);
// for (i = 0; i <= strlen(word)-1; i++)
while ( strlen(word) )
{
abracadabra(word);
putchar('\0');
printf("\n");
word[strlen(word) - 1] = '\0';
}
word[strlen(word)-1] = '\0';
printf("\n");
system("pause");
return 0;
}

Anagram Solver, array[26] not working correctly

I've nearly finished my anagram solver program where I input two strings and get the result of whether they are anagrams of each other. For this example i'm using 'Payment received' and 'Every cent paid me'.
The problem i'm getting is when I output the letterCount arrays, letterCount1 is incorrect (it doesn't think there is a character 'd' but there is.) but letterCount2 is correct.
Can anyone see a problem with this because i'm completely baffled?
#include <stdio.h>
#include <string.h>
int checkAnagram(char string1[], char string2[])
{
int i;
int count = 0, count2 = 0;
int letterCount1[26] = {0};
int letterCount2[26] = {0};
for(i = 0; i < strlen(string1); i++)
{
if(!isspace(string1[i]))
{
string1[i] = tolower(string1[i]);
count++;
}
}
for(i = 0; i < strlen(string2); i++)
{
if(!isspace(string2[i]))
{
string2[i] = tolower(string2[i]);
count2++;
}
}
if(count == count2)
{
for(i = 0; i < count; i++)
{
if(string1[i] >='a' && string1[i] <= 'z')
{
letterCount1[string1[i] - 'a'] ++;
}
if(string2[i] >='a' && string2[i] <= 'z')
{
letterCount2[string2[i] - 'a'] ++;
}
}
printf("%s\n", string1);
for(i = 0; i < 26; i++)
{
printf("%d ", letterCount1[i]);
printf("%d ", letterCount2[i]);
}
}
}
main()
{
char string1[100];
char string2[100];
gets(string1);
gets(string2);
if(checkAnagram(string1, string2) == 1)
{
printf("%s", "Yes");
} else
{
printf("%s", "No");
}
}
That's because your count holds the count of non-space characters, but you keep the strings with the spaces.
For example, the string "hello world" has 11 characters, but if you run it through the loops your count will be 10 (you don't count the space). However, when you later go over the strings and count the appearance of each letter, you will go over the first 10 characters, therefore completely ignoring the last character - a 'd'.
To fix it, you need to go over all characters of the string, and only count the alphanumeric ones.
I fixed it for you:
#include <stdio.h>
#include <string.h>
int checkAnagram(char string1[], char string2[])
{
int i;
int count = 0, count2 = 0;
int letterCount1[26] = {0};
int letterCount2[26] = {0};
int len1 = strlen(string1);
int len2 = strlen(string2);
for(i = 0; i < len1; i++)
{
if(!isspace(string1[i]))
{
string1[i] = tolower(string1[i]);
count++;
}
}
for(i = 0; i < len2; i++)
{
if(!isspace(string2[i]))
{
string2[i] = tolower(string2[i]);
count2++;
}
}
if(count == count2)
{
for (i=0; i<len1; i++)
if (!isspace(string1[i]))
letterCount1[string1[i]-'a']++;
for (i=0; i<len2; i++)
if (!isspace(string2[i]))
letterCount2[string2[i]-'a']++;
int flag = 1;
for(i = 0; flag && i < 26; i++)
if (letterCount1[i] != letterCount2[i])
flag = 0;
return flag;
}
return 0;
}
main()
{
char string1[100];
char string2[100];
gets(string1);
gets(string2);
if(checkAnagram(string1, string2) == 1)
{
printf("%s", "Yes");
} else
{
printf("%s", "No");
}
}
First, don't calculate an string's length inside a loop. I extracted them into len1 and len2 variables.
Second, your loop was wrong! You shouldn't go up to count, you should go up to that string's length.
Third, you didn't return anything from checkAnagram function.

Resources