Why does the while loop stop before the else statement? - c

I want to execute the outputs that are in else statements (True or Nothing) but for some reason, my while loop only executes either first if statement or else if. I know that I am using infinite loop but I want to leave it by using break function that is in one of the two of else statements. What I want is to execute the else statements, so, Do they have hair? ->Y -> Messi? -> Y-> True. Or Do they have hair -> N -> Beckham? -> Y -> True. Or Do they have hair -> N -> Beckham ->N ->Nothing. Or Do they have hair -> T->Messi->N-> Nothing
#include <stdio.h>
#include <strings.h>
int random(char z[]);
int main() {
char *x ="Do they have hair";
char *yes = "Messi";
char *no = "Beckham";
char *u ="Nope";
do {
char *currents = x;
while (1) {
if (random(currents)) {
if (yes) {
currents = yes;
printf("First check\n");
} else {
printf("True: %s\n", yes);
break;
}
} else if (no) {
currents = no;
printf("False\n");
} else {
printf("Nothing\n");
break;
}
}
}while(random("Run Again?"));
return 0;
}
int random(char z[])
{
char a[3];
printf("%s: %s",z,a);
fgets(a, 3,stdin);
return a[0] == 'y';
}

Your while loop is not be quit because if (yes) and if(no) are always true.
yes is Messi. All non-zero value is referenced as true.
So, Your yes value has always the address of memory where Messi is saved. and It's always non-zero.
no is also same. no is always pointing on Beckham. So, It's true
So, I modified the code for your logic. Please refer the following code:
#include <string.h>
#include <iostream>
#include <stdio.h>
int random(char z[]);
int main() {
char x[] = "Do they have hair";
char again[] = "run again";
char yes[] = "Messi";
char no[] = "Beckham";
char u[] = "Nope";
do {
if (random(x)) {
if (random(yes)) printf("True!\n");
else printf("Nothing!\n");
}
else {
if (random(no)) printf("True!\n");
else printf("Nothing!\n");
}
} while (random(again));
return 0;
}
int random(char z[])
{
char a[3];
printf("%s?:", z);
fgets(a, 3, stdin);
return a[0] == 'y';
}

Related

How do i put a word into an array

so this is part of a kind of menu, the only problemis that the word is not getting into the array "frase" i have already tried with frase [ ] = "the word" but idk why it wont work
if(lvl==1)
{
printf("lvl 1\n");
if (opc==1)
{
printf("Animales\n");
a = rand() %3 + 1;
printf("%d", a);
if (a=1)
frase <= "pato";
if (a=2)
frase <="ganso";
if (a=3)
frase <= "avispa";
}
if (opc==2)
{
printf("comida\n");
a = rand() %3 + 1;
if (a=1)
frase <="pasta";
if (a=2)
frase <="pizza";
if (a=3)
frase <="pastel";
}
if (opc==3)
{
printf("paises\n");
a = rand() %3 + 1;
if (a=1)
frase <="peru";
if (a=2)
frase <="brasil";
if (a=3)
frase <="egipto";
}
}
`
I suggest you solve this by modeling your data. In this case with a array of structs. Then you index into to obtain the relevant data:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main() {
struct {
const char *opc;
const char **frase;
} data[] = {
{"Animales", (const char *[]) { "pato", "ganso", "avispa" }},
{"comida", (const char *[]) { "pasta", "pizza", "pastel" }},
{"paises", (const char *[]) { "peru", "brasil", "egipto" }}
};
srand(time(0));
int opc = rand() % 3;
printf("lvl 1 %s %s\n", data[opc].opc, data[opc].frase[rand() % 3]);
return 0;
}
If you have a lot of data put the data in a file and write a function to build the struct at start-up. A special case of this approach is to store the data in a lightweight database like SQLite, then you can query for the relevant data at run-time or load it all it upon start-up.
You many no longer need to copy the frase, but if you want to use a strcpy:
char frase[100];
strcpy(frase, data[opc].frase[rand() % 3]);
Multiple things to be improved in the code. The if(a=1) should be changed to ==. Not sure what you mean by frase<="pato", strcpy or strncpy should be used. Please refer the following sample code.
void copytoarray(char *array, char *word, unsigned int len)
{
if(array == NULL || word == NULL)
{
return;
}
strncpy(array, word, len);
}
int main(void) {
char frase[15] = {'\0'};
int a, lvl =1;
int opc =1;
if(lvl==1)
{
printf("lvl 1\n");
if (opc==1)
{
printf("Animales\n");
a = rand() %3 + 1;
printf("%d\n", a);
if (a==1)
copytoarray(frase, "pato", strlen("pato"));
if (a==2)
copytoarray(frase, "ganso", strlen("ganso"));
if (a==3)
copytoarray(frase, "avispa", strlen("avispa"));
}
}
printf("Word: %s\n ",frase);
}

C function isn't working

I am writing a function Calculate_age_when_Trump_elected(int year_born) to return a result and assign a value to age_when_Trump_elected.
The result should be the YEAR_TRUMP_ELECTED minus the year of Trump was born but currently it just shows the input that the user enters.
"terminal_user_input.c" is just a file for functions read_string and read_integer.
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include "terminal_user_input.c"
#define YEAR_TRUMP_ELECTED 2016
// A very basic read boolean function
bool read_boolean(const char* prompt)
{
my_string answer;
bool result;
answer = read_string(prompt);
answer.str[0] = (char) tolower(answer.str[0]);
switch (answer.str[0]) {
case 'n':
result = false;
break;
case 'x':
result = false;
break;
default:
result = true;
}
return result;
}
int Calculate_age_when_Trump_elected(int year_born)
{
int result;
result = YEAR_TRUMP_ELECTED - year_born;
return 0;
}
int main()
{
my_string name;
int age_when_Trump_elected;
int year_born;
bool brexiter;
name = read_string("What is your name? ");
year_born = read_integer("When you were born? ");
age_when_Trump_elected = Calculate_age_when_Trump_elected(year_born);
printf("You were %d years old when Trump was elected\n",year_born);
brexiter = read_boolean("Are u a Brexit support? ");
if (brexiter == true)
{
printf("%s is a Brexit supporter\n",name.str);
}
else
{
printf("%s isn't a Brexit supporter\n",name.str);
}
read_string("Type 'exit' to continue ");
return 0;
}
Look at Calculate_age_when_Trump_elected. It will always return 0. You should return the result variable instead.

Python's binascii.unhexlify function in C

I'm building a program that takes input as if it is a bare MAC address and turn it into a binary string. I'm doing this on a embedded system so there is no STD. I have been trying something similar to this question but after 2 days I haven't achieved anything, I'm really bad with these kind of things.
What I wanted is output to be equal to goal, take this into consideration:
#include <stdio.h>
int main() {
const char* goal = "\xaa\xbb\xcc\xdd\xee\xff";
printf("Goal: %s\n", goal);
char* input = "aabbccddeeff";
printf("Input: %s\n", input);
char* output = NULL;
// Magic code here
if (output == goal) {
printf("Did work! Yay!");
} else {
printf("Did not work, keep trying");
}
}
Thanks, this is for a personal project and I really want to finish it
First, your comparison should use strcmp else it'll be always wrong.
Then, I would read the string 2-char by 2-char and convert each "digit" to its value (0-15), then compose the result with shifting
#include <stdio.h>
#include <string.h>
// helper function to convert a char 0-9 or a-f to its decimal value (0-16)
// if something else is passed returns 0...
int a2v(char c)
{
if ((c>='0')&&(c<='9'))
{
return c-'0';
}
if ((c>='a')&&(c<='f'))
{
return c-'a'+10;
}
else return 0;
}
int main() {
const char* goal = "\xaa\xbb\xcc\xdd\xee\xff";
printf("Goal: %s\n", goal);
const char* input = "aabbccddeeff";
int i;
char output[strlen(input)/2 + 1];
char *ptr = output;
for (i=0;i<strlen(input);i+=2)
{
*ptr++ = (a2v(input[i])<<4) + a2v(input[i]);
}
*ptr = '\0';
printf("Goal: %s\n", output);
if (strcmp(output,goal)==0) {
printf("Did work! Yay!");
} else {
printf("Did not work, keep trying");
}
}

C boolean function comparing 2 Strings alphabeticly

So I am trying to compare 2 strings and if the first one (x) is smaller than the second one the method twoStrComp should return true, else it should be false.
This is my code, although when I try to run it on my terminal nothing comes up...
As if it ignored my code.. Also I was wondering if it would be more efficient with pointers but I was unsure of how to declare them, can I do twoStrComp(*x,*y)?
ORIGINAL CODE:
#include <stdio.h>
#include <stdbool.h>
bool twoStrComp(char[], char[]);
int main(void)
{
char x[]= "test";
char y[]= "another";
twoStrComp(x,y);
}
bool twoStrComp(char string1[], char string2[] )
{
int i=0, flag=0;
while(flag==0)
{
if (string1[i]<string2[i])
{
flag=-1;
}
else if (string1[i]==string2[i])
{
flag=0;
i++
}
else
{
return 1;
}
}
return flag;
}
new VERSION:
bool twoStrComp(char[], char[]);
int main(void)
{
char x[]= "atest";
char y[]= "another";
bool ans = twoStrComp(x,y);
printf("%s", ans ? "true" : "false");
}
bool twoStrComp(char string1[], char string2[] )
{
int i=0, flag=0;
bool value = false;
while(flag==0) {
if (string1[i]>string2[i])
{
flag=1;
value = false;
}
else if (string1[i]<string2[i])
{
flag=-1;
value = true;
}
else if (string1[i]==string2[i])
{
return 0;
value = true;
}
else
{
i++;
}
}
if(flag == 1)
return (value == false);
if(flag == -1)
return (value == true);
return value;
}
So I am trying to compare 2 strings and if the first one (x) is smaller than the second one the method twoStrComp should return true, else it should be false.
I suggest a better name for your function. It is no generic compare function but it's more a isSmaller function. You don't care about separate cases for identical or larger values.
This is my code, although when I try to run it on my terminal nothing comes up
If you want to see anything on your console, you need to print something. You can use printf for that purpose.
Also I was wondering if it would be more efficient with pointers but I was unsure of how to declare them, can I do twoStrComp(*x,*y)?
If you want to pass pointers, you can declare it like this:
bool twoStrComp(const char *x, const char *y)
But....
Passing arrays as parameters results in passing pointers anyway. The array decays to pointers when used in parameter list of a function. You won't see any performance improvement.
Regarding your code...
I refer to the version listed as version 2 in edit history.
You return 1 or -1. As you use type bool for return type, you should think about using TRUE or FALSE. Or at least return 0 in some case.
Setting flag=0; does not have any sense. If it wasn't 0 before, you would have left the loop.
You don't check whether you compare beyond the end of the strings.
A version that fixes those problems and includes some test cases could look like this:
#include <stdbool.h>
#include <stdio.h>
bool twoStrComp(char string1[], char string2[]);
int main(void)
{
char x[]= "test";
char y[]= "another";
bool isSmaller = twoStrComp(x,y);
printf("Is x(%s) smaller than y(%s)? %s\n", x, y, isSmaller ? "YES" : "NO");
isSmaller = twoStrComp(y,x);
printf("Is y(%s) smaller than x(%s)? %s\n", y, x, isSmaller ? "YES" : "NO");
char x2[]= "aaa";
char y2[]= "aab";
isSmaller = twoStrComp(x2,y2);
printf("Is x2(%s) smaller than y2(%s)? %s\n", x2, y2, isSmaller ? "YES" : "NO");
isSmaller = twoStrComp(y2,x2);
printf("Is y2(%s) smaller than x2(%s)? %s\n", y2, x2, isSmaller ? "YES" : "NO");
isSmaller = twoStrComp(x2,x2);
printf("Is x2(%s) smaller than x2(%s)? %s\n", x2, x2, isSmaller ? "YES" : "NO");
}
bool twoStrComp(char string1[], char string2[])
{
int i=0;
while (true)
{
if (string1[i] < string2[i])
return true; // First one smaller than second one...
else if (string1[i] > string2[i])
return false; // First one larger than second one...
else if (!string1[i])
return false; // identical and end of strings reached.
else
i++; // identical, not yet decided.
}
// We cannot get here, but the compiler complains...
return false;
}

Remove the duplicate from a String Using Pointers

#include<stdio.h>
char *removedps(char *x)
{
int Ar[256] = {0};
int ip=0;
int op=0;
char temp;
while(*(x+ip))
{
temp = (*(x+ip));
if (!Ar[temp]) {
Ar[temp] = 1;
*(x+ip) = *(x+op);
op++;
}
ip++;
*(x+op) = '\0';
}
return x;
}
int main()
{
char lo[] = "0001";
printf("%s",removedps(lo));
}
My code is not working
I have tried hard to see the error
All I GET IS the first character .
My idea is simple
make an array of 256 places
insert Zero into them
Then insert 1 for each character inside the string (on that position of the array)
your assignment looks to be the error here.
op is "out postiion", ip is "in position"
so it should be
*(x+op) = *(x+ip);
not the other way.
because *(x+op) = '\0';
is always run every iteration of the loop.
I'd probablly do it more like this ( using your method, which I probablly wouldn't use personally)
char *removedps(char *x)
{
int Ar[256] = {0};
char* start = x;
while(*x)
{
if (Ar[*x])
{ // remove the repeated character
memmove(x, x+1, strlen(x));
}
else
{
Ar[*x] = 1;
x++;
}
}
return start;
}
also, I'd name it remove_duplicate_chars or something, not a fan of cryptic abbreviations.
At the end of the loop, you do *(x+op)='\0';, and then, in the next iteration, you do *(x+ip)=*(x+op);, so from the 2sd iteration, you put there 0.
try do something like:
for (op=ip=0;x[ip];ip++) {
if (!Ar[x[ip]]++) x[op++]=x[ip];
}
x[op]=0;

Resources