Reverse an infix expression in C? [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Such that a string of "23+45" becomes "45+23"?
This is in relation to converting an infix expression to prefix expression, with the goal here being to be able to first reverse the infix expression

The usual way to do so is to code some recursive descent parser building some concrete syntax tree in memory.
So you would first define several struct-s representing the various nodes of that tree (as a tagged union type), then code the parser, then code the transformation of nodes, then code their printer. Read wikipage on abstract syntax trees.
You may want to use parser generators like GNU bison or ANTLR.
You certainly should read books like the Dragon book before coding.
You should also read the documentation of your C compiler (e.g. GCC) and debugger (e.g. GDB)
You could take inspiration from the source code of existing open source programs like GNUmeric or octave or GNUplot or Lua or GNU guile or GNU bash.
PS. For a university homework, mention the source code you did study. Your teacher might be delighted you read them.

Here is a readable and easy to understand solution. It's not the most efficient, but if you are doing infix/postfix notations you are not concern with performance:
/* \brief swap in-place the operands of an expression of form `lhs op rhs` (no spaces)
* where op is a single character operator
*
* \param expr string representing the expression. Must follow specified form
* \param operator single character operator
*
* \post \p expr will contain `rhs op lhs` (no spaces)
*/
void reverse_expr(char* expr, char operator)
{
char* buffer = malloc(strlen(expr) + 1);
char* const operator_pos = strchr(expr, operator);
if (operator_pos == NULL)
{
fprintf(stderr, "invalid expression: missing '%c'", operator);
free(buffer);
exit(1);
}
*operator_pos = '\0';
sprintf(buffer, "%s+%s", expr, operator_pos + 1);
strcpy(expr, buffer);
free(buffer);
}

Related

Can part of a string be copied onto another string in C? But the begin index for copying isn't zero [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
For example, I have this string:
ABABcct
Can I copy
ABc
begin index = 2, end index = 4
...from that string?
Is there any specific built-in function that can do this?
I know strncpy() can copy a number of characters of a string starting from the beginning of the string onto another. But I don't think it can do what I have just described. As far as I know, its "begin index" is limited to 0.
Actually you can use the function strncpy() with a pointer to anywhere in your string, not only a pointer to its beginning.
Example:
char *src = strdup("ABABcct");
char *dest;
strncpy(dest, src + 2, 3) // Copies 3 characters from your pointer src + 2 to your pointer dest
If you run this code, dest will contain ABc.
While in your case the standard copy functions would eventually work, their use is not allowed when the source and the destination are overlapped, in which case you'll experience an UB.
For such issue the standard C library provide the function memmove designed to handle overlapped areas. It works as using an intermediate buffer to solve any overlapping problem.
see also Meaning of overlapping when using memcpy
With strncpy
#include <stdio.h>
#include <string.h>
int main(void)
{
char p[10],s[10]="abcdefgh";
strncpy(p,s+2,3);
puts(p);
return 0;
}
I know strncpy() ... As far as I know, its "begin index" (as I call it) is limited to 0.
You knew it wrong. It's not about begin index or anything - simply you need to pass relevant char* in src and target which is being done here.
To add further clarification - most standard library functions which you are talking about never put a constraint of passing the pointer to the 0-th index. It doesn't matter which index you send - you can send 100th or 50th doesn't matter as long it follows the things expected by function (null termination etc).
The code posted here is for illustration purpose - didn't include the necessary checks needed to use str*cpy functions.

Passing string as a case condition [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
In C language, is it possible to pass string as a case condition in switch case?
If possible, can AI (Artificial Intelligence) be achieved?
Is it possible to pass string as a case condition in switch case?
No - the switch statement only operates on integer values; case labels must be constant integral expressions. You'd have to map the string onto an integer value, either by using a hash function or a lookup table or something.
#define MAX_LEN 80 // or however long you need
#define HELLO_STRING some-integer-value
#define GOODBYE_STRING some-other-integer-value
#define NO_MAPPING 0
int mapToInteger( const char * str )
{
int mapValue = NO_MAPPING;
/**
* logic to map string to integer
*/
return mapValue;
}
int main( void )
{
char inputString[MAX_LEN];
...
while ( fgets( inputString, sizeof inputString, stdin ) )
{
switch( mapToInteger( inputString ) )
{
case HELLO_STRING:
process_hello();
break;
case GOODBYE_STRING:
process_goodbye();
break;
default:
case NO_MAPPING:
i_dont_understand();
break;
}
}
}
Will case or whitespace matter? In other words, should "THIS IS A TEST" and "This is a test" and "tHiS iS a TeSt" all give the same result? If so, then your mapToInteger function (or whatever you decide to call it) will have to take all that into account.
If possible, can AI (Artificial Intelligence) be achieved?
This is the programming equivalent of asking, "if I can use a hammer to nail two pieces of wood together, can I build an apartment complex?" Yeah, sure, but you need to do a bunch of other stuff as well.
The short answer is that a switch in C only accepts integer values, or something easy to cast to an integer (like a character).
There are workarounds tough, like using a hash function or using a series of “if”.
Concerning Artificial Intelligence, this is a vast field, that cannot be addressed with a simple switch. At least for a good result. You can have a look at expert systems as a start.

Comparing the characters [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am writing a code for solving arithmetic expression like:4+3-2*6*(3+4/2)
For that I need to compare the operators in the string with precedence like:
1. ( or )
2. * or /
3. + or -
Can someone tell me how to compare two characters. As their ASCII values are not in the order which I want!
Use a lookup table. If using ASCII, it is just a 256 element table. You index it with the char.
For that I need to compare the operators in the string with precedence
like:
You can do something like this to get a precedence for each character:
int get_precedence (char c) {
switch (c) {
case '+':
case '-': return 3;
case '*':
case '/': return 2;
case '(':
case ')': return 1;
default: return -1;
}
}
That makes it very easy to add in additonal characters as you need.
However, you'll still have some issues. For example, how will you tell unary negation from subtraction? You'll need to look at context for that, because the answer will depend on what comes before. Dealing with infix notation is hard.
To do this yourself, you'll want to write a recursive descent parser or use the shunting yard algorithm. Either way, it'll be several hundred lines of hard code. Then you'll need to decide if you evaluate from the abstract syntax tree or compile to byte code.
I am writing a code for solving arithmetic expression
like:4+3-2*6*(3+4/2)
If you want to solve that in an easy way, you should find a pre-existing library. TinyExpr is one such solution. It's open-source and contained in a single C source code file. Code for that would look like:
#include "tinyexpr.h"
double answer = te_interp("4+3-2*6*(3+4/2)", 0);
Even in ASCII, the order of the integers are still the same. You can compare single digits. For example:
if ('7' > '2') will evaluate to true

Converting char integer representations to binary [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have a char array composed of elements 5 3. The array is used to represent number 53. What should be the approach to convert this number of three chars to its binary equivalent? I am implementing this in C, later on it will need to be rewritten in assembly. The solution I seek should be purely low stuff work without any helper libraries.
I am basically stuck with an idea to convert separately 5 and 4 (via mapping 5 and 4 to their ascii equivalents). Yet the idea would not work for sure. I have another idea to convert char '5' to int 5 by right shifting the byte by 4. Same with 4. Then multiply 5 by 10 and add 4, and then use division by two algorithm to find remainder and compose the binary number.
In C:
int asciToInteger(char *c)
{
int result = 0;
while (*c)
{
result *= 10;
result += (*c - '0');
c++;
}
return result;
}
Assumes input is valid.
You can get a head start on the assembly language version by compiling with certain switches which will output as ... assembly language! For example in GNU C: gcc -S -c ascii2int.c.

Is there a difference between using a[i] and *(a + i)? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Both a[i] and *(a + i) access the i th element of array a.
Are there reasons to prefer one over the other(performance, readability, etc...)?
Neither one is better from a language point of view since they are the same, array indexing should just be syntactic sugar for pointer arithmetic. We can see this from the draft C99 standard section 6.5.2.1 Array subscripting which says (emphasis mine):
[...]The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).[..]
Although for others reading your code a[i] is probably more readable.
a[i] should be preferred, because it is more commonly used and so will be understood more quickly by the person reading the code.
Although they are identical in arrays, I prefer a[i] for the following reason. Suppose you have code like this:
double gradient[3];
// 200 lines later
double dx = gradient[0]; // Works fine
double dy = *(gradient + 1); // Works just as well
Then somebody decided that std::vector looks better than double[]:
vector<double> gradient;
// 200 lines later
double dx = gradient[0]; // Still works
double dy = *(gradient + 1); // Ouch!
Then somebody else decided to go object-oriented all the way:
class Gradient
{
public:
double operator[](int index) const;
};
// 1000 lines later
Gradient gradient;
// 200 lines later
double dx = gradient[0]; // Still works
double dy = *(gradient + 1); // Ouch!!!
Thus, from the viewpoint of maintainability, I prefer to say exactly what I mean, without obscuring the intent with context-dependent synonyms. If I mean "take i-th element of a" then I say exactly that in C++ lingo:
a[i];
rather than relying that for the particular implementation of a one can use a fancier expression for the same.
C has no operator overloading. So you are safe to use whichever you want.
I would use a[i] for clarity when reading the code.
Both are equivalent. Neither one is preferred over other but a[i] is commonly used by programmers. a[i] = *(a + i) = i[a]
As far as I'm concerned (just finished a C course), there is no difference.
Array is implemented as a pointer to the first element on the stack. So a+1 is just the address on the stack after a :)
Edit:
Also, as mentioned by John Bartholomew, even though they are the same, you might want to use a[i] instead - that is the "normal" way to do it (also in other languages) :)
For readability purposes, I would definitely go with a[i].

Resources