I got this code from the internet but I couldnt get the whole code.
for example if(*str) . What does this code mean? and also can a string be returned? I thought that an array in main can be changed
directly in a function but here its been returned..
#include<stdio.h>
#define MAX 100
char* getReverse(char[]);
int main(){
char str[MAX],*rev;
printf("Enter any string: ");
scanf("%s",str);
rev = getReverse(str);
printf("Reversed string is: %s\n\n",rev);
return 0;
}
char* getReverse(char str[]){
static int i=0;
static char rev[MAX];
if(*str){
getReverse(str+1);
rev[i++] = *str;
}
return rev;
}
This is not the clearest example of recursion due to the use of the static variables. Hopefully the code generally seems clear to you, I suspect the part that is confusing to you is the same that was confusing to me at first.
if(*str){
getReverse(str+1);
rev[i++] = *str;
}
So line by line.
if(*str){
If we have not reached the null terminator.
getReverse(str+1);
Call the getReverse function on the next character of the string. It seems pretty straight forward up to here. But it also seems like it may not actually reverse anything because this is the next line
rev[i++] = *str;
We assign index i the character at the beginning of str and increment i but here is the tricky part. i may not be what you think. getReverse gets called before i is incremented. And i is static, so changes will persist between function calls. So, lets say we have a 5 letter word, let say "horse" we will end up with 6 calls on the stack to getReverse. The 6th will not do anything because that is where it finds the null terminator. The trick is that we will then go about resolving the calls in reverse order. First the call where str is pointing to 'e' will resolve and increment i because all the other ones are are still waiting for their calls to getReverse to return. So the last letters are actually the first ones to get added and increment i which is what can be confusing here.
Related
To solve a question, I am looking for a way to stop a loop after it has reached the beginning of the string, assuming the loop starts from the end and decrements, is there an alternative way to do this without finding the length of the string first and decrementing till the number is zero?
Please keep in mind the only functions I can use are malloc, free and write.
This is not possible, because there is nothing special about a string's contents at the beginning. C strings have a "sentinel value" at their end - '\0' - but the first character, and the byte in memory before the first character, can have any value.
is there an alternative way to do this without finding the length of the string first and decrementing till the number is zero?
Apparently you already know where the end of the string is. I suppose you must have a pointer to the terminator character, since you think you do not know the string length.
If finding the length of the string is a viable option at all, however, then you must already know where the beginning is, too. And if you know where the beginning is and you know where the end is, then you already know the length: it is end - beginning. But you do not need to keep a separate counter to iterate backward from the end of a string to the beginning, supposing that you do know where both the end and the beginning are. You can simply use pointer comparisons instead. For example:
int count_a_backwards(const char *beginning, const char *end) {
int count = 0;
for (const char *c = end; c > beginning; ) {
if (*--c == 'a') count += 1;
}
return count;
}
If in fact you do not know where the beginning of the string is, however, then you cannot identify it at all, at least not in the general case. Perhaps you can recognize the beginning if you have some kind of prior knowledge about the string's contents, or about its alignment, or some such, but in general, the beginning of a string cannot be recognized.
Please keep in mind the only functions I can use are malloc, free and
write.
If you are using the function malloc then the function returns pointer to the first byte of the allocated memory. So if the allocated array will contain a string then its beginning will be known.
The task is to find the end of the string.
You can use either the standard C function strlen or write your own loop that will find the end of the stored string.
So if you have two pointers, one that points to the beginning of a string and the second that points to the end of the same string then to traverse the string in the reverse order is not a hard work.
Pay attention to that if you have a character array that contains a string like this
char s[] = "Hello";
then the expressions s, s + 1, s + 2 and so on all points to a string correspondingly "Hello", "ello", "llo" and so on.
You could find the beginning of a string having a pointer to its end provided that the first element of the array contains a unique symbol that is a sentinel value. However in general this is a very rare case.
Here is a demonstrative program that shows how you can traverse a string in the reverse order without using standard C string functions except a function that places a string in a dynamically allocated array.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
enum { N = 12 };
char *s = malloc( N );
strcpy( s, "Hello World" );
puts( s );
char *p = s;
while ( *p ) ++p;
while ( p != s ) putchar( *--p );
putchar( '\n');
free( s );
return 0;
}
The program output is
Hello World
dlroW olleH
This is a sample snippet from a book. I am not understanding how it is printing the string in reverse. The first time reverse is called, the element at 0 is not null assuming of course a valid string was entered. In the else statement, we are calling the function again passing in the address of element at index 1.
So let's say I input "hello". Then I am passing the address of e. The second time reverse is called, however, how is the string being traverse? The index being checked is still 1. Also, it seems to me we are not replacing the values of the array. When we start printing the values with putchar I get so confused that the value at index 0 starts with the last element of the array. I understand that when we use recursion and we hit the base case, and since the items are put on the stack, we start reading them from the top of the stack pointer until the end which is why is in reverse. But here I don't see that happening.
The hard-coded indexes at
reverse( &ptr[1]);
putchar(ptr[0]);
do not make sense to me. I guess I am having difficulty seeing how the string is being traverse when it is the same address being passed each time in the recursion. Please help me understand what is happening.
I have modified the code a bit for simplicity but it does the same thing the one in the book does.
#include <stdio.h>
void reverse(char * ptr);
int main(){
char sentence[10];
printf("enter text \n");
fgets(sentence, 10, stdin);
printf("The line is: \n");
reverse(sentence);
return 0;
}
void reverse( char * ptr){
if(ptr[0] == '\0'){
return;
} else{
reverse( &ptr[1]);
putchar(ptr[0]);
printf("\n");
}
}
The &ptr[1] is equivalent to ptr + 1. Now, if you think of ptr as a number (which it is, really) it should be obvious that it's not the same number being passed every time, but rather one greater for each level of recursion. It's basically passing a substring starting from the second character, only in C the substring is not a separate object but rather a pointer to a different position in the same string.
My problem is: Input the string then replace the word that we want to change
For example: input: i love coke
word: coke
replace: pepsi
result: i love pepsi
But when i run this code it crashed. Can you help show me the mistake?
#include <stdio.h>
#include<string.h>
char replace(char s1[100],char s2[100],char s3[100])
{
int k,i,j;
for(i=0;i<strlen(s1);i++)
for(j=0;j<strlen(s2);j++)
for(k=0;k<strlen(s3);k++)
{
if(s1[i]==s2[j])
{
s1[i]=s3[k];
}
}
return s3;
}
int main()
{
char s1[100],s2[100],s3[100];
printf("input string: ");gets(s1);
printf("Find string: ");gets(s2);
printf("Replace: ");gets(s3);
printf("Result: %s",replace(s1,s2,s3));
return 0;
}
I suggest you use a 4th buffer to store the generated result. You won't be able to replace locally if the word to be replaced and the new word aren't the same length.
Also, you are comparing characters individually. Just because you found a c doesn't automatically mean you found coke and that you should replace it. You must check the entire word is there before replacing anything. Use strstr() to locate substrings inside a string.
In addition, your function is returning a char, it should return a string (char *).
Furthermore, there are plenty of examples online on how to write a function to replace words on a string, so lets not be reduntant. Google it.
Strings in C are null terminated e.g. "i love coke\0". The string length does not include the null terminator. Because of this you are overwriting the null terminator after the 'e' with the 'i' in "pepsi".
A quick hack to check if null terminating the string would help, is to memset s1, s2, and s3 to 0.
Your approach doesn't quite work. What you need to do is search the input string for the word you wish to replace. So, before you even start switching things around, you need to search for the whole word you wish to replace.
Once you find that word, you need to then put in your new word in it's place, and then start searching for the word again untill you finish your input string.
So, for pseudo code:
for i in input //for every letter
if input[i] != lookfor[0]
results[i] put input[i] into new "results" array
else // We might have found it.
for j in lookfor // Go through coke, one at a time
if input[i+j] != lookfor[j] "c,o,k,e"
break; //You didn;t find coke, just "c" or "co" or "cok"
// If you got all the way through, you found coke.
//So now you have to switch that out for the new that in the result
results[i] = "pepsi" //Just be careful here, because this has a different index than i, because pespi's length != coke's length
Did that make sense?
First of all, your replace function is returning to char instead of char*. You can also define your function's return type as void and can make it return to char* buffer (in/out) parameter after in-function string operations. Moreover, you can use strtok(), strcmp() and strstr() predefined string.h functions to accomplish any kind of string operations.
Check this out to get information about standart string operation functions: String Operations
I'm new to C and I'm trying to solve one of the exercise problem of K&R book. The problem is to detect the whether a given string ends with the same content of other string.
For example, if string one is ratandcat and string two is cat. Then it is true that string two ends in string one. To solve this, I came up with half a solution and I got struck with pointers.
My idea is to find the position where string one ends and also the position the string two starts, so that I can proceed further. I have this code:
int strEnd(char *s,char *t){
int ans,slength =0 ,tlength = 0;
while(*s++)
slength++;
while(*t++)
tlength++;
s += slength - tlength;
printf("%c\n",*t);
printf("%c\n",*s);
return ans;
}
void main() {
char *message = "ratandcat";
char *message2 = "at";
int a = strEnd(message,message2);
}
But strangely this outputs :
%
(and a blank space)
But I want my s pointer to point to a. But it doesn't. Whats going wrong here?
Thanks in advance.
One problem is that you have incremented the s pointer to the end of the string, and then you add more stuff to it. You could do that loop with something like:
while(s[slength])
++slength;
Another problem is that you are assuming that the s string is longer than the other. What if it's not? And fix the ; problem noted by Simon.
You have an extra semicolon at the end of
while(*t++);
This means that tlength is never incremented, as only the semicolon (empty statement) is executed in the loop.
I know it's a little unorthodox and will probably cost me some downvotes, but since it's due in 1 hour and I have no idea where to begin I thought I'd ask you guys.
Basically I'm presented with a string that contains placeholders in + form, for example:
1+2+5
I have to create a function to print out all the possibilities of placing different combinations of any given series of digits. I.e. for the series:
[9,8,6] // string array
The output will be
16265
16285
16295
18265
18285
18295
19265
19285
19295
So for each input I get (number of digits)^(number of placeholders) lines of output.
Digits are 0-9 and the maximum form of the digits string is [0,1,2,3,4,5,6,7,8,9].
The original string can have many placeholders (as you'd expect the output can get VERY lengthly).
I have to do it in C, preferably with no recursion. Again I really appreciate any help, couldn't be more thankful right now.
If you can offer an idea, a simplified way to look at solving this, even in a different language or recursively, it'd still be ok, I could use a general concept and move on from there.
It prints them in different order, but it does not matter. and it's not recursive.
#include <stdlib.h>
#include <stdio.h>
int // 0 if no more.
get_string(char* s, const char* spare_chr, int spare_cnt, int comb_num){
for (; *s; s++){
if (*s != '+') continue;
*s = spare_chr[comb_num % spare_cnt];
comb_num /= spare_cnt;
};
return !comb_num;
};
int main(){
const char* spare_str = "986";
int num = 0;
while (1){
char str[] = "1+2+5";
if (!get_string(str, spare_str, strlen(spare_str), num++))
break; // done
printf("str num %2d: %s\n", num, str);
};
return 0;
};
In order to do the actual replacement, you can use strchr to find the first occurrence of a character and return a char * pointer to it. You can then simply change that pointer's value and bam, you've done a character replacement.
Because strchr searches for the first occurrence (before a null terminator), you can use it repeatedly for every value you want to replace.
The loop's a little trickier, but let's see what you make of this.