C: Search vor endindex of first occurence - c

how can i write following programm:
• a function which searches a string in a second string and returns the endindex of the first occurence
• a function which includes all occurences of the first string in the second string, which will be replaced by a third string
• a main function which scans the three strings and puts the string out within the replacement
it is not allowed to use more headers than stdio.h , stdlib.h and string.h
i could only start with a code like this, as you can see i couldnt solve any of the three problems. i hope you can help me.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int endIdx(char *string1, char *string2, char *occu)
{
for (int i = 0; i < strlen(string1); i++)
{
for (int j = 0; j < strlen(string1); j++)
{
if (string1[i] == string2[j])
{
printf("occurence string1[%d] is in string2[%d]\n", i, j);
occu[j] = string1[i];
}
}
}
return 0;
}
int main()
{
char string1[20];
char string2[20];
char occu[20];
printf("Type in the first string: ");
scanf("%s", string1);
printf("Type in the second string: ");
scanf("%s", string2);
endIdx(string1, string2, occu);
printf("%s\n", occu);
}

The following program uses strstr to implement your endIdx-problem.
strstr returns a pointer to the first occurrence of searchTeram in str, or NULL, if it does not occur.
In the first case, we get a start index by taking occurrence - str, i.e. the memory address of the first occurrence minus the memory address where str starts. Adding then the length of searchTerm gives the end index.
In the second case, we simply return -1:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
long endIdx(const char *str, const char *searchTerm) {
long result = -1;
const char* occurrence = strstr(str,searchTerm);
if (occurrence != NULL) {
result = (occurrence - str) + strlen(searchTerm);
}
return result;
}
int main(void)
{
// ----------------012345678901234
const char* str = "Hello world! world is beautiful!";
const char* searchTerm = "world";
long endidx = endIdx(str, searchTerm);
printf("endidx (should be 11): %ld\n", endidx);
endidx = endIdx(str, "not to be contained");
printf("endidx (should be -1): %ld\n", endidx);
return 0;
}

Related

How to locate and convert to integers an array of string in C?

I have a problem I am trying to solve. I have an array of string and integers and I want to convert only the integers(163) to actual integers in C.
I have managed to locate my desired numbers (163) array location but i am unsure how to convert them to numbers. I have tried to use strtol, atoi and strtoumax but I havent been succesful.
I have added my code below.
char busy[30] = {"this is; it was; 163; 234;;"};
int tag = 0;
int location = 0;
for (int i = sizeof(busy); i > 0; i--) {
printf("%c\n", busy[i]);
if (busy[i] == ';') {
tag = tag+1;
printf("tag is %i \n", tag);
}
if (tag == 4) {
printf("for loop is %i\n", i);
location = i;
break;
}
}
location = location+1;
int loca_saved = 0;
int loca_finish = 0;
int tag1 = 0;
while (busy[location] != ';') {
if (busy[location] == ' ' && busy[location - 1] == ';') {
//printf("not printing whitespace between semicolon and characters\n");
location++;
}
else {
if (tag1 == 0) {
tag1 = tag1+1;
loca_saved = location; //this is to tell me the array location for the first char
}
if (busy[location + 1] == ';') {
loca_finish = location; //this is to tell me the array location for the last char
}
putchar(busy[location]); //this is to print my desired characters(163)
location++;
}
}
strspn and strcspn can be used to parse a string.
Instead of sscanf, strtol could be used to get the number.
#include <stdio.h>
#include <string.h>
int main ( void) {
char busy[] = "this is; it was; 163; 234;";
char *dlm = "0123456789";
char *parse = busy;
int number = 0;
while ( *parse) {
parse += strcspn ( parse, dlm);//count to next delimiter
if ( 1 == sscanf ( parse, "%d", &number)) {
printf ( "%d\n", number);
}
parse += strspn ( parse, dlm);//skip delimeters
}
return 0;
}
Parsing could also work off the semicolon.
Some fields will not have an integer.
#include <stdio.h>
#include <string.h>
int main ( void) {
char busy[] = "this is; it was; 163; 234;";
char *dlm = ";";
char *parse = busy;
int number = 0;
while ( *parse) {
if ( 1 == sscanf ( parse, "%d", &number)) {
printf ( "%d\n", number);
}
else {
printf ( "could not parse integer\n");
}
parse += strcspn ( parse, dlm);//count to next delimiter
parse += strspn ( parse, dlm);//skip delimeters
//the above line will skip all consecutive delimiters
//to process each delimiter use the line below
//++parse;//skip one delimiter
}
return 0;
}
Since you have a modifiable string you can use strtok to separate it into substrings based on the ; delimiter. This code does that in in case a substring is a number, it gets printed.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void)
{
char str[30] = {"this is; it was; 163; 234;;"};
for(char* p=strtok(str, ";"); p!=NULL; p=strtok(NULL,str))
{
char* endptr;
int i = strtol(p,&endptr,10);
if(endptr != p)
{
printf("%d\n", i);
}
}
}
Output:
163
234
strtol sets the "endptr" parameter to point at the beginning of the string in case it fails, so we can use that to determine if a substring was a number or not.
It all depends on the exact grammar that you would like to parse. Note, for example, that negative integers start with a - character, and that there has to be a maximum integer value. Since you are working quite "low level", you may want to perform the conversion to an integer while you are reading the string, e.g.:
#include <ctype.h>
#include <stdio.h>
int main(void)
{
char busy[30] = {"this is; it was; 163; 234;;"};
for (char *p = busy; *p; ++p) // Loop over the string
if (isdigit(*p)) // Found first digit of an unsigned integer
{
unsigned n = (unsigned) (*p - '0'); // Store the value of the first digit in 'n'
// While reading the number, shift the digits to the appropriate positions
while (isdigit(*++p))
n = n * 10U + (unsigned) (*p - '0');
printf("%u\n", n); // We have finished parsing the integer, print it
}
}
Using atoi can also work, but it will require two passes over each integer: one in atoi itself and another one to move past the integer in the string you're parsing.
The function strtol allows you to pass a pointer to your pointer which is set to one place after the read integer, which avoids the issue. You can use this to advance the pointer. In this code example, the pointer is either advanced manually or by strtol:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char busy[30] = {"this is; it was; 163; 234;;"};
for (char *p = busy; *p; )
if (isdigit(*p))
printf("%ld\n", strtol(p, &p, 10));
else
++p;
}
Another alternative, without the use of isdigit:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char busy[30] = {"this is; it was; 163; 234;;"};
for (char *p = busy; *p; )
{
char *end;
long n = strtol(p, &end, 10);
if (p != end) // Pointer was advanced, so an integer was read
{
printf("%ld\n", n);
p = end;
}
else // Pointer was not advanced, do so manually
++p;
}
}

string length in c without using string library

char* str =
"\
a-a-a-a\
differing the text, because that was the lecture thing\
the text has been changed\
I know!\
the text has been changed\
";
i deeply thinking about this for hours but can`t figure it out..
with using only stdio.h
string.h is not allowed, but using only basic things..
how can I get string length? someone please help me.
the goal is to find frequency of input pattern in a given string
ex) ha => 2, di => 1..
help me.
As for length of string, the implementation of strlen isn't very complicated.
All you should do is to loop over the string until you find a \0 (end of string) and count the number of times you looped.
unsigned int mystrlen(const char* str)
{
unsigned int length = 0;
while (*str != 0)
{
str++;
length++;
}
return length;
}
This could be shortened into
unsigned int len = 0;
for (; str[len]; len++);
A string in pure C is just a pointer to a memory.
IF the last element is 0, then you can use strlen or whatever checks for that.
But if that is not the case you need to memorize the length in a variable.
So if it is 0-terminated just loop to the first element that is 0 (not '0') and thats the end. If you counted the elements you have the string-length.
This works for some test input string, but i higly recommend to check it with more cases.
Suppose we have implemented strstr().
strstr()
Is a C library function from string.h Library
char *strstr(const char *haystack, const char *needle)
This function finds the first occurrence of the substring needle in the source string haystack.
The terminating \0 characters are not compared.
source: TutorialsPoint
(with some edition)
Code
#include <stdio.h>
#include <string.h>
unsigned int Neostrlen(const char* str)
{
unsigned int length = 0;
while (*str != 0)
{
str++;
length++;
}
return length;
}
int BluePIXYstrlen(char* str)
{
int len = 0;
sscanf(str, "%*[^0]%n", &len);
return len;
}
int Jeanfransvastrlen(char* str)
{
int i;
for (i=0;str[i];i++);
return i;
}
int main(int argc, char **argv){
//is it true, no need to malloc????
char* str =
"\
P-P-A-P\
I have a pen, I have a apple\
Uh! Apple-Pen!\
I have a pen, I have pineapple\
Uh! Pineapple-Pen!\
Apple-Pen, Pineapple-Pen\
Uh! Pen-Pineapple-Apple-Pen\
Pen-Pineapple-Apple-Pen\
";
printf("len: %d\n", Jeanfransvastrlen(str));
printf("len: %d\n", Neostrlen(str));
printf("len: %d\n", BluePIXYstrlen(str));
printf("sss:%s\n\n\n", str);
char * search = "have";//search for this substring
int lenSr= Neostrlen(search);
printf("lenSr: %d\n", lenSr);
char * ret;
ret = strstr(str, search);
int count = 0;
while (ret){
//printf("The substring is: %s\n\n\n\n", ret);
count++;
for (int i=0;i<lenSr;i++){
printf("%c", ret[i]);
}
printf("\nEnd sub\n");
for (int i=0;i<lenSr;i++){
ret++;
}
ret = strstr(ret, search);
}
printf("count: %d\n", count);
return 0;
}
Edited
For only using stdio.h you can substitute all strstr() with this version of mystrstr() adopted from leetcode
mystrstr()
char* mystrstr(char *str, const char *target) {
if (!*target) {
return str;
}
char *p1 = (char*)str;
while (*p1) {
char *p1Begin = p1, *p2 = (char*)target;
while (*p1 && *p2 && *p1 == *p2) {
p1++;
p2++;
}
if (!*p2){
return p1Begin;
}
p1 = p1Begin + 1;
}
return NULL;
}
Hint
I removed const from first first argument of mystrstr() because of I want to change it later, and this is the only changed i have made on original code.
This version is sensitive to Uppercase and lowercase letters in string,
for example Apple is differ from apple.
As chux said in comments my code return substrings of "ababa" from source
"aba" only {aba} not more. and this is because i change string pointer inside while in last for.
Suggestion
Try to implement your version of strstr(), and strlen()

How to scan a string for specific terms

I'm trying to scan user input text for specific words and then, when those words occur, print them to the console.
#import <Foundation/Foundation.h>
#include <stdio.h>
int main(){
char cArray[] = "example";
char cInput[] = "";
char cOutput[] = "";
printf("\nType your message:\n");
for (int y=0; y<1; y++){
fgets(cInput, 120, stdin);
}
printf("\nInitialised character array:\n");
for (int x=0; x<1; x++){
if(strncmp(&cInput[x], &cArray[x], 120) == 0){
strncpy(cOutput, cArray, strnlen(cInput, +1));
printf("%s\n", cOutput);
break;
}
}
}
Output:
Type your message:
example
Initialised character array:
Program ended with exit code: 120
Appreciate any feedback as I'm still learning :)
Thanks.
The edited code:
#include <stdio.h>
#include <string.h>
#define MAX_STR_LEN 120
int main(){
char *cArray[MAX_STR_LEN] = {"example", "this"};
char cInput[MAX_STR_LEN] = "";
char cOutput[MAX_STR_LEN] = "";
printf("Type your message:\n");
for (int y=0; y<1; y++){
fgets(cInput, MAX_STR_LEN, stdin);
char * ptr = cInput;
while((ptr=strstr(ptr, *cArray)) != NULL){
strncpy(cOutput, ptr, strlen(*cArray));
printf("Initialised string array:\n%s\n", cOutput);
ptr++;
}
}
}
Works although I'm encountering a different problem now. The output only seems to register one word before it completes, thus only "example" is printed.
Output:
Type your message:
this is an example
Initialised string array:
example
Program ended with exit code: 0
char cInput[] = "";
The sizeof this array is 1.
fgets(cInput, 120, stdin);
This is array out of bound write which will lead to undefined behavior.
Have
char cInput[120] = "";
You need to take care of
char cOutput[120] = "";
also. Since you are trying to write to this array after comparing.
You need strstr function from string.h
const char * strstr ( const char * str1, const char * str2 );
the following gives you an example of usage:
#include <stdio.h>
#include <string.h>
#define MAX_STR_LEN 120
int main(){
char cArray[MAX_STR_LEN] = "example"; // string to be searched in the input string
char cInput[MAX_STR_LEN] = ""; // input string
char cOutput[MAX_STR_LEN] = ""; // buffer for found string
printf("\nType your message:\n");
for (int y=0; y<1; y++){ // this loop from original example looks strange, but it works
fgets(cInput, MAX_STR_LEN, stdin);
}
// search in the input string
char * ptr;
if( ( ptr=strstr(cInput, cArray) ) != NULL)
{
//copy the string to cOutput
strncpy(cOutput, ptr, strlen(cArray));
// output the found string
printf("String that was found: \n%s\n", cOutput);
}
else
{
printf("String was not found in the input!\n");
}
}
EDIT:
If you want to all the strings, use the following loop instead of if-else:
// search in the input string
char * ptr = cInput;
while( ( ptr=strstr(ptr, cArray) ) != NULL)
{
//copy the string to cOutput
strncpy(cOutput, ptr, strlen(cArray));
// output the found string
printf("String \"%s\" was found at position %d\n", cOutput, (int)(ptr - cInput + 1));
// find next string
ptr++;
}

I need to know how many times a string appears within another one! Using C

Well, the title already says what I need. I tried to use a loop but it didn't go well, so, I came for your help guys!
Here's my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char word[31], word2[31];
int size1, size2;
int i, j, k; // control
int count = 0;
printf ("\nInput the first word");
scanf ("%s", word);
printf ("\nInput the second word: ");
scanf (" %s", word2);
// I tried to make a loop through the first string and if it matches a letter, it would loop through the others (if they are equal, we have a substring), but failed to put it on the `for` loop
printf ("'%s' appears %d times within '%s'", word2, count, word);
return 0;
}
strstr is a useful function, it shortens your code considerably; when you find a match, just try again with the rest of the string;
#include <string.h>
#include <stdio.h>
int main()
{
const char* source = "aabaa";
const char* string2find = "aa";
int occurrences;
const char *ptr, *lastfind = NULL;
for(ptr=source; (lastfind=strstr(ptr, string2find)); ptr=lastfind+1)
occurrences++;
printf("%d\n", occurrences);
return 0;
}
...or if you're really set on doing it without string.h functions, the code gets a bit more verbose;
#include <string.h>
#include <stdio.h>
int main()
{
const char* source = "aaabaa";
const char* string2find = "aa";
int count=0;
const char *position;
for(position=source; *position; position++) {
int comparepos, equal=1;
for(comparepos=0; string2find[comparepos]; comparepos++) {
if(position[comparepos] != string2find[comparepos]) {
equal = 0;
break;
}
}
count+=equal;
}
printf("%d\n", count);
return 0;
}
Use strstr to find occurence of string in other string:
#include <stdio.h>
#include <string.h>
int main () {
char* a = "aaaa";
char* b = "aa";
char* c;
int count = 0;
for(c = a; *c; c++){
if(strstr(c, b)){
count++;
}
}
printf("count %d\n", count);
}
Also, use strlen to find length of a string..

In C find position of substring in a string

Here is a program to accept a:
Sentence from a user.
Word from a user.
How do I find the position of the word entered in the sentence?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char sntnc[50], word[50], *ptr[50];
int pos;
puts("\nEnter a sentence");
gets(sntnc);
fflush(stdin);
puts("\nEnter a word");
gets(word);
fflush(stdin);
ptr=strstr(sntnc,word);
//how do I find out at what position the word occurs in the sentence?
//Following is the required output
printf("The word starts at position #%d", pos);
return 0;
}
The ptr pointer will point to the beginning of word, so you can just subtract the location of the sentence pointer, sntnc, from it:
pos = ptr - sntnc;
Just for reference:
char saux[] = "this is a string, try to search_this here";
int dlenstr = strlen(saux);
if (dlenstr > 0)
{
char *pfound = strstr(saux, "search_this"); //pointer to the first character found 's' in the string saux
if (pfound != NULL)
{
int dposfound = int (pfound - saux); //saux is already pointing to the first string character 't'.
}
}
The return of strstr() is a pointer to the first occurence of your "word", so
pos=ptr-sntc;
This only works because sntc and ptr are pointers to the same string. To clarify when I say occurence it is the position of the first matching char when the matching string is found within your target string.
You can use this simple strpos modification
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int strpos(char *haystack, char *needle, int offset);
int main()
{
char *p = "Hello there all y'al, hope that you are all well";
int pos = strpos(p, "all", 0);
printf("First all at : %d\n", pos);
pos = strpos(p, "all", 10);
printf("Second all at : %d\n", pos);
}
int strpos(char *hay, char *needle, int offset)
{
char haystack[strlen(hay)];
strncpy(haystack, hay+offset, strlen(hay)-offset);
char *p = strstr(haystack, needle);
if (p)
return p - haystack+offset;
return -1;
}
For some reasons I was having trouble with strstr(), and I also wanted index.
I made this function to find the position of substring inside a bigger string (if exists) otherwise return -1.
int isSubstring(char * haystack, char * needle) {
int i = 0;
int d = 0;
if (strlen(haystack) >= strlen(needle)) {
for (i = strlen(haystack) - strlen(needle); i >= 0; i--) {
int found = 1; //assume we found (wanted to use boolean)
for (d = 0; d < strlen(needle); d++) {
if (haystack[i + d] != needle[d]) {
found = 0;
break;
}
}
if (found == 1) {
return i;
}
}
return -1;
} else {
//fprintf(stdout, "haystack smaller\n");
}
}
My comment to the ORIGINAL post in this thread:
This declaration is INCORRECT:
char sntnc[50], word[50], *ptr[50];
C code would not even compile : it will fail on this line:
ptr = strstr(sntnc,word);
So the line shall be changed to :
char sntnc[50], word[50], *ptr;
And you do NOT need memeory allocated to 'ptr string'. You just need a pointer to char.

Resources