You make the usual mistake:
movie_temp[i]==movie[i];
should be
movie_temp[i]=movie[i];
Your compiler should have been screaming a warning at you... mine did:
note: use '=' to turn this equality comparison into an assignment
movie_temp[i]==movie[i];
Context (in case you have trouble finding the line):
if(movie[i]==ch)
{
movie_temp[i]==movie[i]; // <<<<<<<<<< this is the line that doesn't copy!
count1++;
}
update just following the warnings that the compiler was giving me, I made a few small changes to your code and now it is working. Mostly, I was heeding the "you are not returning a value!" types of warnings (when you don't explicitly return a value, the compiler will make something up - and most likely you won't find the result useful).
The key is to move the line
return movie_temp;
outside of the for
loop in check_movie2
:
char* check_movie2(char movie[], char movie_temp[], char ch)
{
for(int i=0 ; movie[i]!='\0' ; i++)
{
if(movie[i]==ch)
{
movie_temp[i]=movie[i];
}
}
return movie_temp;
}
There are other problems - but this is the one that was biting you the hardest.
Lesson learnt: if your compiler is warning you, LISTEN.
For your entertainment here is the code that I got to run (and that "mostly works". It doesn't currently print out lives correctly and it asks for input after I guessed the title. Also you might consider making the comparison case-insensitive as you are currently sensitive to correct capitalization).
updated added some comments and additional fixes in your code.
#include<iostream>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
using namespace std; // <<<< if you want to use 'cout' instead of 'std::cout' etc, you need this
void display_movie(char movie_temp[], int);
void display_life(int);
int win_player2(char movie_temp[]);
int check_movie(char movie[], char movie_temp[], char, int);
void display_movie(char movie_temp[], int len)
{
for(int i=0 ; i<len ; i++)
cout<<movie_temp[i];
}
void display_life(int life) //displays lives left after each guess
{
for(int i=0 ; i<=life ; i++)
cout<<"+"; // <<<<< I don't know what you are hoping to print with "\3"
// <<<<< Remember that `\` has a special meaning inside a string!
}
int check_movie(char movie[], char movie_temp[], char ch, int life)
{
int count1=0;
for(int i=0 ; movie[i]!='\0' ; i++)
{
if(tolower(movie[i])==tolower(ch)) // <<<<< consider case insensitive match
{
movie_temp[i]=movie[i];
count1++;
}
}
if(count1==0)
{
life--;
return life; //if none of the character is found, life is reduced by 1.
count1=0;
}
return life; // <<<<<< return life here
}
int win_player2(char movie_temp[])
{
int count=0;
for(int i=0 ; movie_temp[i]!='\0' ; i++)
{
if(movie_temp[i]=='_')
count++;
}
return (count==0)?0:1;
}
char* check_movie2(char movie[], char movie_temp[], char ch)
{
for(int i=0 ; movie[i]!='\0' ; i++)
{
if(movie[i]==ch)
{
movie_temp[i]=movie[i];
}
}
return movie_temp;
}
int main()
{
char movie[100], movie_temp[100], ch;
cout<<"Enter the movie: ";
cin.getline(movie,100);
int len= strlen(movie);
int life=9;
system("cls");
for(int i=0 ; movie[i]!='\0' ; i++)
{
if(movie[i]=='a' || movie[i]=='e' || movie[i]=='i' || movie[i]=='o' ||
movie[i]=='u' || movie[i]==' ')
movie_temp[i]= movie[i];
else
movie_temp[i]='_';
} //initially displays the movie to player 2 and shows only vowels.
cout<<"\nLives left: ";
display_life(life);
while(life!=0 && win_player2(movie_temp)!=0) // <<<<< change || to &&
{
cout<<"\n";
display_movie(movie_temp, len);
cout<<"\nEnter your guess: ";
cin>>ch;
life=check_movie(movie, movie_temp, ch, life);
/*I need to update the life after each round, or else the initially declared
life is passed. */
cout<<"\n\nLives left: ";
display_life(life);
}
return 0;
}
UPDATE - "returning pointers from functions"
To "return an array of values", you need to realize a number of things:
- A function can only "return" a simple value (int, float, pointer, ...)
- If you create an array inside a function, you need to make sure the
space allocated remains valid after you return
- You can pass a pointer to a function, and let the function update values in the space pointer to
Simple example (C) on different approaches (including one that doesn't work):
does not work:
int * foo() {
int A[]={1,2,3,4,5};
return A;
}
int main(void) {
int *X;
X = foo();
printf("%d", X[0]); // UNDEFINED BEHAVIOR
return 0;
}
This doesn't work because the array A
stops existing ('goes out of scope') when the function returns. Accessing memory pointed to by X
results in undefined behavior.
works, but only use in single threaded environment:
int * foo() {
static int A[]={1,2,3,4,5};
return A;
}
this works because the array is static
so it is allocated differently and "survives" after the function returns. Not recommended.
pass a pointer and size of array: (example increments an array)
void foo(int *a, int n) {
int ii;
for(ii=0;ii<n;ii++) a[ii]++;
}
int main(void) {
int n=5;
int X[5] = {1,2,3,4,5};
foo(X, 5); // values in X will be incremented in-place
Returning value in another array:
void foo(int *A, int *B, int n) {
int ii;
for(ii=0; ii<n; ii++) B[ii] = 2 * A[ii];
}
int main(void) {
int a[5] = {1,2,3,4,5};
int b[5];
foo(a, b, 5);
printf("%d\n", b[0]); // returns a value of 2
return 0;
}
This is starting to be more sensible. Finally, if you want an array to be created by the function, you can do
int *foo(int n) {
int *X, ii;
X = malloc(n * sizeof *X);
for(ii = 0; ii < n; ii++) X[ii] = 2 * ii;
return X;
}
int main(void) {
int *a;
a = foo(5);
printf("%d", a[4]); // will print 8
free(a); // remember to do this after you finished using the array or you get a memory leak!
return 0;
}
I hope these additional examples and their explanation improves your understanding of these techniques a little bit.