C boolean function comparing 2 Strings alphabeticly - c

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

Related

Checking balanced parentheses in a string with stacks in c

I am trying to write a program where i implement stacks with arrays and use them to check if a given string has balanced parentheses.
For ex. if inputted '(()){}[()]' ,program would output 'Balanced', otherwise if inputted '({})[' the program would output 'Not balanced'.
This part is the array implementation of the stack.
#include <stdio.h>
#include <stdlib.h>
#define MAX 50
int stack[MAX];
int top=-1;
void push(char val){
if(top==MAX-1){
printf("stack is already full,error\n");
}else{
top++;
stack[top]=val;
}
}
char pop(){
if(top==-1){
printf("not enough elements,error\n");
exit(1);
}else{
top--;
return stack[top];
}
}
This part is the implementation of a common method to solve the problem.
int isMatching(char c1, char c2){
if(c1=='{' && c2=='}')
return 1;
else if(c1 =='(' && c2==')')
return 1;
else if(c1=='[' && c2==']')
return 1;
return 0;
}
int isBalanced(char str[]){
int i=0;
while(str[i]!='\0'){
if(str[i]=='{' || str[i]=='[' || str[i]=='('){
push(str[i]);
}
if(str[i]==')' || str[i] == ']' || str[i]=='}'){
if(stack==NULL){
return 0;
}
if(!isMatching(pop(), str[i])){
return 0;
}
}
i++;
}
if(stack==NULL){
return 1; // balanced parenthesis
}else{
return 0; // not balanced parenthesis
}
}
And this is the main function where the user inputs a string and it's tested if it's 'Balanced' or not.
int main(){
char str[MAX];
int flag;
printf("Enter the string with the brackets and etc.\n");
fgets(str, sizeof(str),stdin);
flag=isBalanced(str);
if(flag==1){
printf("Balanced\n");
}
else{
printf("Not balanced\n");
}
return 0;
}
When i input a very simple example, i get a wrong answer, for instance
Enter the string with the brackets and etc.
()
Not balanced
This is supposed to output 'Balanced' instead.I don't understand how this could have occured.
in pop(), you are decrementing before returning the top element. Change:
top--;
return stack[top];
to
return stack[top--];
Also, in isBalanced(), stack is NEVER null, so delete:
if(stack==NULL){
return 0;
}
and change the balanced check to look for the empty stack from:
if(stack==NULL){
return 1; // balanced parenthesis
}else{
return 0; // not balanced parenthesis
}
To:
if(top==-1){
return 1; // balanced parenthesis
}else{
return 0; // not balanced parenthesis
}
After making these changes, your code appeared to work on my box. This isn't quite how I'd have coded it, but this is the minimal set of changes to make it work.
if (stack==NULL) is the problem here, stack will never be NULL.
You need to check if there are still elements in your stack, by verifying that top > 0
You implemented the push/pop combo wrong. If you push one character top becomes 0. If you popping it immediately it finally executes top--; return stack[top], which evaluates to stack[-1].
Try this push/pop:
int top=-1; //idx to be popped next; <0 -> invalid
void push(char val)
{
if(top==MAX-2)
printf("stack is already full,error\n");
else
stack[++top]=val;
}
char pop()
{
if(top<0) return '\0'; //no abort, just return invalid char
return stack[top--];
}
The answer to your question has already been satisfactorily answered, but as a suggestion for a different approach, consider the following.
Since there are only a very small number of common enclosures used within C source code you can easily track pairs of them using an increment-decrement counter. The following uses a struct, typedefed to balanced_s which is encapsulated into a function to simplify the evaluation. Following is a sample implementation:
typedef struct {
int paren;
int curly;
int square;
bool bBal
}balanced_s;
balanced_s * balanced_enclosures(const char *source);
int main(void)
{
char in[5000] = {0};//you could improve this by reading file size
//first then creating array sized accordingly
FILE *fp = fopen("C:\\play\\source.c", "r");//using copy of this source to test
if(fp)
{
size_t bytes = fread(in, 1, sizeof(in), fp);
}
balanced_s * b = balanced_enclosures(in);
bool balanced = b->bBal;//If not true, inspect the rest of the
//members to see where the imbalance has occurred.
free(b);
return 0;
}
balanced_s * balanced_enclosures(const char *source)
{
balanced_s *pBal = malloc(sizeof(*pBal));
memset(pBal, 0, sizeof(*pBal));
while(*source)
{
switch(*source) {
case '(':
pBal->paren++;
break;
case ')':
pBal->paren--;
break;
case '{':
pBal->curly++;
break;
case '}':
pBal->curly--;
break;
case '[':
pBal->square++;
break;
case ']':
pBal->square--;
break;
}
source++;
pBal->bBal = (!pBal->paren && !pBal->curly && !pBal->square);
}
return pBal;
}

Why does the while loop stop before the else statement?

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

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

Very Basic Encryption

#include <stdio.h>
int limit;
char alp[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'};
void encode(char message[21],char enc_message[21],int key);
void decode(char enc_message[21],char dec_message[21],int key);
main()
{
int key,i=0,j=0;
char message[21];
char enc_message[21];
char dec_message[21];
char encrypted[21];
char a='\0';
printf("Input the characters to encrypt\n");
while(i<21 && a!='\n')
{
scanf("%c",&a);
message[i]=a;
i=i+1;
}
for(i=0;;i++) /*custom strlen*/
{
if( message[i]= '\0')
{
limit=i;
break;
}
}
printf("Input the key");
scanf("%d",key);
for(i=0;i<21;i++)
{
enc_message[i]=message[i];
}
encode(message[21],enc_message[21],key);
for(i=0;i<21;i++)
{
dec_message[i]=enc_message[i];
}
for(i=0;i<limit;i++)
{
printf("%c",enc_message[i]);
}
printf("\n\n");
decode(enc_message[21],dec_message[21],key);
for(i=0;i<limit;i++)
{
printf("%c",dec_message[i]);
}
}
void encode(char message[21],char enc_message[21],int key)
{
/*char temp[21];*/
int x,y;
for(x=0;x<limit;x++) /* message check */
{
for(y=0;y<26;y++) /* <----- alphabet check */
{
if (enc_message[x]==alp[y]) enc_message[x]=alp[y+key];
}
}
}
/*------------------------------------------------------------------------*/
void decode(char enc_message[21],char dec_message[21],int key)
{
int x,y;
for (x=0;x<limit;x++)
{
for(y=0;y<26;y++)
{
if (dec_message[x]==alp[y+key]) dec_message[x]=alp[y];
}
}
}
The compiler says,the mistake has to do with the way I call functions(and write them)and says: passing argument1 of 'encode' makes pointer from integer without a cast ,and that is for argument 2 of 'encode' and the exact same for 'decode'
Thanks in advance!
You are passing a single element and it's not even a valid element, try
decode(enc_message, dec_message, key);
Also, format your code so it's readable that is really important, and looping to compute the length of the string to use it in another loop is not a very smart thing, print it in a loop like
for (int i = 0 ; enc_message[i] != '\0' ; ++i) ...
also, don't over use break, just think about the logical condition for the loop, it's the same one where you break. Code is much more readable if the condition appears in the right place.

Error with bool function

I am a new C developer (I am used to programming in Java), and have tried create, what I thought was a simple bool function. Although I am getting an error which I don't understand how to fix:
#include <stdio.h>
#include <stdlib.h>
typedef enum { false, true } bool;
int main() {
int currentNumber, round = 1;
printf("Numbers generated will be between 1 and 20. \n");
currentNumber = rand() % 20;
bool validNumber = false;
do {
if(currentNumber != 0) {
validNumber == true;
} else {
currentNumber = rand() % 20;
}
}while(validNumber == false);
printf("You're on round" + ("%d", round));
printf("You're current number is: " + ("%d", currentNumber));
printf("Higher or Lower (H/L)?");
char userInput [20];
scanf("%s", &userInput);
if((userInput[0] == 'h') || (userInput[0] == 'H')) {
completeRound(round, 'H', currentNumber);
} else if((userInput[0] == 'l') || (userInput[0] == 'L')) {
completeRound(round, 'L', currentNumber);
}
}
void completeRound(int round, char input, int currentNumber) {
int initialVal = currentNumber, newVal;
if(input == 'H') {
newVal = rand() % 20;
bool checkResult(initialVal, newVal, input);
} else {
newVal = rand() % 20;
bool checkResult(initialVal, newVal, input);
}
}
bool checkResult(int initialVal, int finalVal, char input);
bool checkResult(int initialVal, int finalVal, char input) {
if(input == 'H') {
if(initialVal <= finalVal) {
return true;
} else {
return false;
}
}
if(input == 'L') {
if(initialVal >= finalVal) {
return true;
}else {
return false;
}
}
printf("An error has occurred! Aborting game...");
return false;
}
The error is as follows:
\main.c|39|error: conflicting types for 'checkResult'
At first, I thought that for some reason, in C you could only pass certain data types as arguments to a bool method, although I can not find a straight answer to this on Google. Other than that; I can not understand what it means by "conflicting types" (this is the first time I've debugged a C program.
The function I have used to call checkResult is as follows:
Before calling the function you need to write its prototype also. By default compiler is considering it as return type of int but actually it is bool.
so write bool checkResult(int initialVal, int finalVal, char input) before calling checkResult.
You probably have a typo in your code. The line
bool checkResult(initialVal, newVal, temp);
implicitly creates a prototype for a bool function. The types of the arguments are omitted and default to int in C versions prior to C99. This declaration is in conflict with the actual declaration, whose third parameter is of type char.
You probably meant something like this:
bool okay = checkResult(initialVal, newVal, temp);
This defines a bool variable okay and initialises it with the result of the function call. (But note that this variable is local to the current scope, so in your example you'd lose the result immediately.)
It is legal in C to declare a function inside a function body, although it is not good practice. It is more usual to declare them in headers or at the beginning of the file.
As of C99, implicit function declarations are invalid. There also isn't a default argument or function return type of int. You might consider to enforce the C99 standard (eg with -std=c99in gcc) to avoid falling into the implicit-declaration trap.
You have called functions before declaring them.So is the error. Because by default the return type of a c function is "int".
Add
void completeRound(int , char , int );
and
bool checkResult(int , int , char);
after your typedef (better this way than declaring them in body of the calling function).
And since checkResult() is returning a value of type bool you better assign it to a variable of type bool like
bool okay = checkResult(initialVal, newVal, temp); this.

Resources