C program to find substring in string - c

So I may be attacking this the wrong way; I was learning a bit of Javascript and wrote a program that will find a string contained in another string and store the matches in an array (sorry if that didn't make too much sense, seeing my C program should help). I tried to translate my program to C, but it doesn't work; I think my issue is data types:
int main () {
char text[58];
strcpy(text, "I am James, James the Great, a pretty cool guy named James");
char store[16];
char name[6] = "James";
for (int i = 0; i <= 16; i++) {
if (text[i] == 'J') {
for (int k = i; k < i + 6; k++) {
store[k] = text[i];
}
}
}
int a = sizeof(store) / sizeof(store[0]);
for (int b = 0; b < a; b++) {
/* This should print out the values stored in the store array */
printf("%d", store[b]);
}
return 0;
}
My expected result would be something like:
JamesJamesJames
Instead I get:
10000747474747474-6374747474
So I'm assuming it's doing exactly what I told it to do, just not storing the letters into the array as letters, a bit confusing. Is there a better way to do this?
This is the javascript code I was trying to translate:
var text = "I am James, James the Great, a pretty cool guy named James";
var myName = "James";
var hits =[];
for (i = 0; i < text.length; i++) {
if (text[i] === "J") {
for (var j = i; j < i + myName.length ; j++) {
hits.push(text[j]);
}
}
}
if (hits.length === 0) {
console.log("Your name wasn't found!");
} else{
console.log(hits);
}

You are going to break store[] with this line
for (int k = i; k < i + 6; k++) {
because you are writing to the same index as you found the text in text[]. You also loop one too many times (6)
int ind = 0;
for (int k = 0; k < 5; k++) {
store[ind++] = text[i+k];
}
Then your next statement doesn't tell you anything about the data you collected
int a = sizeof(store) / sizeof(store[0]);
Just remove it, and print ind characters from store[].

You made following mistakes.
for (int i = 0; i <= 16; i++)
You iterate by '16' but this isn't proper length of text.
for (int k = i; k < i + 6; k++)
So you iterate by "i, i+1, i+2, i+3, i+4, i+5, i+6" here is 7 chars, "James" have 6.
store[k] = text[i];
You aren't changing "i" value so text[i] always return 'J'. It's better to use savePoistion variable so do I in the following code.
int a = sizeof(store) / sizeof(store[0]);
for (int b = 0; b < a; b++) {
/* This should print out the values stored in the store array */
printf("%d", store[b]);
}
I have no idea what are you trying to do here. It's really unnecessary.
printf("%d", store[b]);
"%d" means that you are printing integers so don't be surprised that your output was numbers. Just simply printf("%s\n", store);
This should look like this
int main () {
char text[58];
strcpy(text, "I am James, James the Great, a pretty cool guy named James");
char store[20];
int len = strlen(text);
int savePosition = 0;
int i, k;
for (i = 0; i < len; i++) {
if (text[i] == 'J') {
for ( k = i; k < i + 5; k++) {
store[savePosition] = text[k];
++savePosition;
}
}
}
store[savePosition] = '\0';
printf("%s\n", store);
return 0;
}

int main (void) {
char text[] = "I am James, James the Great, a pretty cool guy named James";
char name[] = "James";
char store[16] = {0};
int store_index = 0;
for (int i = 0; i < strlen(text); i++) {
if (text[i] == 'J') {
for (int k = i; k < i + strlen(name); k++) {
store[store_index++] = text[k];
}
}
}
if(strlen(store)==0) {
printf("Your name wasn't found!\n");
} else {
printf("%s\n", store);
}
return 0;
}
rewrite version.
int main (void) {
char text[] = "I am James, James the Great, a pretty cool guy named James";
char name[] = "James";
char store[sizeof(text)];
char *p = strstr(text, name);
if(p == NULL) {
printf("Your name wasn't found!\n");
} else {
int len = strlen(name);
int index = 0;
do {
memcpy(store + index, name, len);
index += len;
p = strstr(p + len, name);
} while(p != NULL);
store[index] = 0;
printf("%s\n", store);
}
return 0;
}

Related

How can I take this values to an array?

I am trying to take this input from terminal.
ARRAY [1,2,3,4,5,6]
and pass the numbers to an array like this.
else if (strncmp(input, "CONSTRUCT", 9) == 0) {
printf("CONSTRUCT\n");
// CONSTRUCT [value1,value2,value3,...,valueN]
int i = 0;
char *token;
char *str = strdup(input);
char **array = str_split(str, '[');
char **array2 = str_split(array[1], ']');
char **array3 = str_split(array2[0], ',');
int array4[100];
for (i = 0; i < 100; i++){
array4[i] = atoi(array3[i]);
}
for (i = 0; i < 100; i++){
printf("%d\n", array4[i]);
}
for (i = 0; i < 100; i++){
root = insert(root, array4[i]);
}
printf("\n");
}
here you simply run off the end of an array
char** array3 = str_split(array2[0], ',');
int array4[100];
for (i = 0; i < 100; i++)
{
array4[i] = atoi(array3[i]);
}
array3 is dynamically sized to number of numbers + 1, but you try to access 100 entries
you placed a null entry at the end of the list, use that
int count = 0;
for (i = 0; i < 100; i++)
{
if (array3[i] == NULL)
break;
count++;
array4[i] = atoi(array3[i]);
}
for (i = 0; i < count; i++)
{
printf("%d\n", array4[i]);
}
for (i = 0; i < count; i++)
{
root = insert(root, array4[i]);
}
I saw your comment about the space. this code does not work with a space after 'CONSTRUCT', thats because
scanf("%s", input);
reads up to the first space - you want fgets.

Sorting case sensitive array not working in C

I'm trying to sort a case sensitive array of words words[number of words][number of letters] alphabetically by strcmp using case insensitive array with same words. When I sort case insensitive array using case insensitive array and print it, it works, but if I try to sort case sensitive array using case insensitive array - it does not. Below are the blocks of code I am using to do this.
char cs_sns[20][20];
///scan here as you wish/////
char cs_ins[20][20];
for(int i = 0; i < 20; i++)
{
strcpy(cs_ins[i], cs_sns[i]);
}
//////////////////CONVERT///////////////////////////
for(int i = 0; i < 20; i++)
{
strlwr(cs_ins[i]);
}
/////////////////SORT_CASE_SENSITIVE_BY_LOWERCASE/////////////////////
for (int j = 0; j < 20; j++)
{
for (int i = 0; i < 20-1; i++)
{
int x = (strcmp(cs_ins[i], cs_ins[i+1]) > 0);
if (x == 1)
{
char temp[20];
strcpy(temp, cs_sns[i]);
strcpy(cs_sns[i], cs_sns[i+1]);
strcpy(cs_sns[i+1], temp);
}
}
}
/////////////////////SORT_LOWERCASE_BY_LOWERCASE/////////////////
for (int j = 0; j < 20; j++)
{
for (int i = 0; i < 20 - 1; i++)
{
int x = (strcmp(cs_ins[i], cs_ins[i+1]) > 0);
if (x == 1)
{
char temp[20];
strcpy(temp, cs_ins[i]);
strcpy(cs_ins[i], cs_ins[i+1]);
strcpy(cs_ins[i+1], temp);
}
}
}
///////////////PRINT/////////////////
for (int i = 0; i < 20; i++)
{
printf("%s\n", cs_sns[i]); //////////swap with cs_ins[i] and see what happens
}
Below is the stolen function strlwr to convert to lowercase.
///////////define strlwr/////////////////////
char *strlwr(char *str)
{
unsigned char *p = (unsigned char *)str;
while (*p)
{
*p = tolower((unsigned char)*p);
p++;
}
return str;
}
You'll need to include ctype.h for tolower.
What is it that I am missing?
Thank you.
Edit: Can be solved by stricmp, here is a link:
C99 remove stricmp() and strnicmp()?
Still curious tho...
The problem occurs because you are trying to sort your case-sensitive array according to the case-insensitive array, while NOT CHANGING the insensitive array.
This may work:
/////////////////SORT_CASE_SENSITIVE_BY_LOWERCASE/////////////////////
for (int j = 0; j < 20; j++)
{
for (int i = 0; i < 20-1; i++)
{
int x = (strcmp(cs_ins[i], cs_ins[i+1]) > 0);
if (x == 1)
{
char temp[20];
strcpy(temp, cs_sns[i]);
strcpy(cs_sns[i], cs_sns[i+1]);
strcpy(cs_sns[i+1], temp);
//swap elements in cs_ins[] as well
strcpy(temp, cs_ins[i]);
strcpy(cs_ins[i], cs_ins[i+1]);
strcpy(cs_ins[i+1], temp);
}
}
}
Thus applying the changes to the insensitive array as well.
Of course, just using stricmp would be a much simpler solution, as Monica has stated.

C language - operation replaces mutiple array elements instead of one

I am in the process of creating hangman in C language, but there is one problem that I cannot quite grasp. When a user correctly guesses one of the letters that the word that is being guessed has, the program replaces all of previously guessed letters to the one user just put. What is the source of this problem?
#include<stdio.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int x = 0, isCompleted, matchFound, numberOfTries = 7;
char letterGuess[1];
int randomIndex = rand()%14;
const char *wordArray[14];
const char *guessedWord[10];
const char *usedLetters[17];
for (int k = 0; k < 10; k++) {
guessedWord[k] = "_";
}
wordArray[0] = "butonierka";
wordArray[1] = "centyfolia";
wordArray[2] = "chiroplast";
wordArray[3] = "cmentarzyk";
wordArray[4] = "chrustniak";
wordArray[5] = "budowniczy";
wordArray[6] = "cholewkarz";
wordArray[7] = "cornflakes";
wordArray[8] = "brzydactwo";
wordArray[9] = "germanofil";
wordArray[10] = "lichtarzyk";
wordArray[11] = "lutowniczy";
wordArray[12] = "mikrocysta";
wordArray[13] = "tryskawiec";
const char *wordToGuess = wordArray[randomIndex];
for(int i = 0; i < 10; i++) {
printf(" %s ", guessedWord[i]);
}
printf("\n");
while(numberOfTries != 0 && isCompleted != 10) {
matchFound = 0;
isCompleted = 0;
printf("Please give a lowercase letter\n");
printf("Left tries: %d\n", numberOfTries);
scanf("%s", &letterGuess);
for (int z = 0; z < 17; z++) {
if (usedLetters[z] == letterGuess[0]) {
matchFound = 1;
}
}
if (letterGuess[0] >= 'a' && letterGuess[0] <= 'z' && matchFound == 0) {
usedLetters[x] = letterGuess[0];
x++;
for (int j = 0; j < 10; j++) {
if (letterGuess[0] == wordArray[randomIndex][j])
guessedWord[j] = letterGuess;
matchFound = 1;
}
}
if (matchFound == 0) {
numberOfTries--;
}
for(int z = 0; z < 10; z++) {
printf(" %s ", guessedWord[z]);
}
printf("\n");
} else {
if (matchFound == 1) {
printf("You've already given such letter!!\n");
} else {
printf("Wrong input, please try again!\n");
}
}
for (int k = 0; k < 10; k++) {
if (guessedWord[k] != "_") {
isCompleted++;
}
}
if (isCompleted == 10) {
printf("You have correctly guessed a word! Congrats!!\n");
}
printf("\n\n");
}
printf("The word was: %s\n", wordArray[randomIndex]);
printf("Game over!!\n");
}
The problem is that you're storing letterGuess, rather than individual characters. So each time letterGuess is updated with a new guess, all references to it change. Also, letterGuess is too short, leaving no room for the terminating null character.
The best solution is to make letterGuess a char (or an int), not an array, and to make guessedWord a char [] rather than a char *[]. There is no reason to use strings for single characters. That will solve the string-sharing problem.

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

Program not encrypting properly with spaces

I have tried to create an implementation of a vigenere cipher, but have come across a hurde in the form of the program not working properly when given spaces in the input. (Assume keyword bacon)
With Spaces
Input
Meet me
Correct Output
Negh zf
Actual Output
Negh Ne
Without Spaces
Input
Meetme
Ouput
Neghzf
So clearly the program is working for strings without the spaces. Anywhere here is the code and thanks in advance for help.
#include <string.h>
#include <stdio.h>
#include <ctype.h>
char encrypt(int key, char a);
int hash(char a);
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("You need a keyword!");
return 1;
}
string keyword = argv[1];
for (int j = 0; j != strlen(keyword); ++j)
{
if (!isalpha(keyword[j]))
{
printf ("The keyword needs to be all words!");
return 1;
}
}
string text = GetString();
for (int i = 0, j = 0; i != strlen(text); ++i, ++j)
{
if (j == strlen(keyword))
{
j = 0;
}
int key = 0;
if (isupper(keyword[j]))
{
key = keyword[j] - 'A';
text[i] = encrypt(key, text[i]);
}
else if (islower(keyword[j]))
{
key = keyword[j] - 'a';
text[i] = encrypt(key, text[i]);
}
else if (isspace(text[i]))
{
j = j - 1;
}
}
printf ("%s\n", text);
}
char encrypt(int key, char a)
{
if (isalpha(a))
{
int total = (int) a + key;
if (isupper(a))
{
while (total > 90)
{
total = total - 26;
}
}
else if (islower(a))
{
while (total > 122)
{
total = total - 26;
}
}
return (char) total;
}
else
{
return a;
}
}
the problem is inside your for loop. Try to correct it in the following way (you will understand easily the mistake):
for (int i = 0, j = 0; i != strlen(text); ++i, ++j)
{
if (j == strlen(keyword))
{
j = 0;
}
// the following check mmust be done here
if (isspace(text[i])) {
j = j - 1;
}
int key = 0;
if (isupper(keyword[j]))
{
key = keyword[j] - 'A';
text[i] = encrypt(key, text[i]);
}
else if (islower(keyword[j]))
{
key = keyword[j] - 'a';
text[i] = encrypt(key, text[i]);
}
}
It looks like you are reading your words from command line arguments; however, command line arguments are typically separated by whitespace. Your program doesn't know that those spaces are supposed to be part of the input.
You need to change the way you are reading input.

Resources