Reading input through stdin using fgets error - c

For class, I have to write a code that checks for balanced parentheses. The input will be given through stdin (running it as: code.exe < in.txt)
The input is formatted like this:
CASE 1: (())
CASE 2: [})(
CASE n: ...
***end***
I coded it like this:
int main(void) {
char test[200];
char str[200];
char end[] = "***end***";
int caseNo = 1;
int j;
int flag;
while(1) {
if(strcmp(fgets(test, 200, stdin), end) == 0) {
break;
} else {
strcpy(str, test);
int len = strlen(str);
for(int i = 0; i < len; i++) {
if(str[i] == ':') {
j = i + 2;
break;
}
}
flag = balanced_parenthesis(str, j);
if(flag == 0) {
printf("CASE %d: NOT BALANCED\n", caseNo);
} else if(flag == 1) {
printf("CASE %d: BALANCED\n", caseNo);
}
caseNo++;
}
}
But, the output that comes out is wrong. I've already checked my balanced_parenthesis function separately, and it does work, which leads me to believe that the error is in reading the input.
Am I using fgets or strcmp wrong? Is there a better way to read the input?
Edit:
Full Code is shown here:
#include <stdio.h>
#include <string.h>
int top = -1;
char stack[200];
void push(char c) {
top++;
stack[top] = c;
}
char pop() {
return(stack[top--]);
}
int pairs(char open, char close) {
if(open == '(' && close == ')') {
return 1;
} else if (open == '[' && close == ']') {
return 1;
} else if (open == '{' && close == '}') {
return 1;
}
return 0;
}
int balanced_parenthesis(char str[], int j) {
int len = strlen(str);
for(int i = j; i < len; i++) {
if((str[i] == '(') || (str[i] == '[') || (str[i] == '{')) {
push(str[i]);
}
if((str[i] == ')') || (str[i] == ']') || (str[i] == '}')) {
if(top == -1) { //empty
return 0;
} else {
char temp = pop();
if(pairs(temp, str[i]) == 0) {
return 0; //not pairs
}
}
}
}
if(top == -1) {
return 1; //balanced
} else {
return 0; //not balanced
}
}
int main(void) {
char test[200];
char str[200];
char end[] = "***end***";
int caseNo = 1;
int j;
int flag;
while(1) {
if(fgets(test, 200, stdin) == NULL) {
break;
} else {
test[strcspn(test, "\n")] = '\0';
if(strcmp(test, end) == 0) {
break;
} else {
strcpy(str, test);
int len = strlen(str);
for(int i = 0; i < len; i++) {
if(str[i] == ':') {
j = i + 2;
break;
}
}
flag = balanced_parenthesis(str, j);
if(flag == 0) {
printf("CASE %d: NOT BALANCED\n", caseNo);
} else if(flag == 1) {
printf("CASE %d: BALANCED\n", caseNo);
}
caseNo++;
}
}
}
}
Sample Input:
CASE 1: ([[]{()}])()
CASE 2: ()[]{}
CASE 3: (([[]))
CASE 4: (()}
CASE 5: (()()()())
CASE 6: (((())))
CASE 7: (()((())()))
CASE 8: ((((((())
CASE 9: ()))
CASE 10: (()()(()
CASE 11: ][
CASE 12: ({)}
***end***
Expected Output:
CASE 1: BALANCED
CASE 2: BALANCED
CASE 3: NOT BALANCED
CASE 4: NOT BALANCED
CASE 5: BALANCED
CASE 6: BALANCED
CASE 7: BALANCED
CASE 8: NOT BALANCED
CASE 9: NOT BALANCED
CASE 10: NOT BALANCED
CASE 11: NOT BALANCED
CASE 12: NOT BALANCED

There is a logical flaw in your code:-
for every line that you wish to check - before that you must ensure to rest the state of the stack. That's what you didn't do which caused problem.
void stack_reset(){
top = -1;
}
In main()
...
if(strcmp(test, end) == 0) {
break;
} else {
reset();
strcpy(str, test);
...
This change will make your code work. Otherwise it was handling with previous state also.
As you have \n as input to the char array test your comparison fails.
Considering that your rest of the code is alright , there is a single change you need to do to make this work. (This is problem if there is \n at the end of the input file). It is still good to add this solution - that will make this solution work irrespective of newline at the last line of the file.
while(1) {
if( !fgets(test, 200, stdin) ){
/* error handling*/
}
test[strcspn(test,"\n")]='\0';
if(strcmp(test, end) == 0) {
break;
} else {
...
You are overwriting the \n with the \0 because strcspn returns the number of character read before it encounters any of the character specified in the second parameter to strcspn.
Also once return statement is executed there is no use of the break statement as control never reach that point. And you exit from the function.
if(pairs(temp, str[i]) == 0) {
return 0; //not pairs
// break; <-- not needed.
}
The way you took input won't fail when you have the input file ended with no newline. If there is then the last comparison with ***end*** will fail.
The reason behind making the reset() function separate from your main() module is that - if later you need to change the implementation of stack then the user code won't be affected. It can still call the reset() and be sure that it will reset the state of the stack. Also as another suggestion, try not to make the stack variable top global, even better if you can pass the structure from function to function instead of using global one.

Related

Check if the input string consisting of braces is well-formed

I have spent the last two hours trying to debug my code that is supposed to check if the input consists of well-formed brackets. What I mean by well formed is that ()()[] or ([()]) are acceptable but ((((() is not.
I'm not allowed to use any header file apart from <stdio.h>
#include <stdio.h>
void cross(char str[], int i, int j) {
str[i] = 'X';
str[j] = 'X';
}
int iscrossed(char str[]) {
int i = 0;
while (str[i] != '\0') {
if (str[i] != 'X')
return 0;
i++;
}
return 1;
}
int check(char str[]) {
int i = 1, j;
while (str[i] != '\0') {
if (str[i] == ')') {
for (j = i - 1; j >= 0; j--) {
if (str[j] == '(') {
cross(str, str[i], str[j]);
}
break;
}
} else
if (str[i] == ']') {
for (j = i - 1; j >= 0; j--) {
if (str[j] == '[') {
cross(str, str[i], str[j]);
}
break;
}
}
i++;
}
if (iscrossed(str) == 1)
return 1;
else
return 0;
}
int main() {
char str[20];
scanf("%s", str);
printf("%d\n", check(str));
}
For certain inputs the program prints a zero followed by a segmentation fault and for the others it just prints a zero.
Please keep in mind that I'm a beginner programmer so please don't include too much heavy stuff in your hints. I'd be grateful for any help on this.
Edit: It would be wonderful if your answer tells me the errors in my code, because that was my question in the first place.
Here a simple recursive solution:
#include <stdio.h>
int brace(const char **s, char cc)
{
while(1) {
if(**s == cc) { return 0; }
switch(**s) {
case '\0': return -1;
case '[': ++(*s); if(brace(s, ']')) { return -1; } ++(*s); break;
case '{': ++(*s); if(brace(s, '}')) { return -1; } ++(*s); break;
case '(': ++(*s); if(brace(s, ')')) { return -1; } ++(*s); break;
case ']':
case '}':
case ')': return -1;
default: ++(*s);
}
}
}
int check_brace(const char *s)
{
return brace(&s, '\0');
}
int main()
{
printf("%d\n", check_brace(" hekl(l o{ asdf } te)ts()({})"));
}
Returns -1 when somethings wrong. Otherwise 0.
There are multiple problems in your code:
you call cross(str, str[i], str[j]); instead of cross(str, i, j); when you find matches for parentheses and brackets.
the break statement should be moved inside the if block.
your method does not allow detection of nesting errors
your method would have undefined behavior if str is an empty string (which you cannot input via scanf())
Here is a modified version:
#include <stdio.h>
void cross(char str[], int i, int j) {
str[i] = str[j] = 'X';
}
int iscrossed(char str[]) {
int i = 0;
while (str[i] != '\0') {
if (str[i] != 'X')
return 0;
i++;
}
return 1;
}
int check(char str[]) {
int i = 0, j;
while (str[i] != '\0') {
if (str[i] == ')') {
for (j = i - 1; j >= 0; j--) {
if (str[j] == '(') {
cross(str, i, j);
break;
}
}
} else
if (str[i] == ']') {
for (j = i - 1; j >= 0; j--) {
if (str[j] == '[') {
cross(str, i, j);
break;
}
}
}
i++;
}
return iscrossed(str);
}
int main() {
char str[80];
if (scanf("%79s", str) == 1) {
printf("%d\n", check(str));
}
return 0;
}
Here is a simpler alternative:
#include <stdio.h>
const char *check(const char str[], int endc) {
while (str) {
int c = *str++;
switch (c) {
case '(': str = check(str, ')'); break;
case '[': str = check(str, ']'); break;
case '{': str = check(str, '}'); break;
case ')':
case ']':
case '}':
case '\0': return c == endc ? str : NULL;
}
}
return NULL;
}
int main() {
char str[80];
if (fgets(str, sizeof str, stdin)) {
printf("%d\n", check(str, '\0') != NULL);
}
return 0;
}
Pseudocode of a possible answer:
initialize char[] unclosed
int latest_unclosed_index = -1
for each char in string {
if char == opening_bracket {
latest_unclosed_index += 1
unclosed[latest_unclosed_index] = char
} else if char == closing_bracket {
if latest_unclosed_index < 0 {
return false
} else if char == closing_of(unclosed[latest_unclosed_index]) {
unclosed[latest_unclosed_index] = null
latest_unclosed_index -= 1
} else {
return false
}
}
}
if latest_unclosed_index == -1 {
return true
} else {
return false
}
This works by keeping an array of all unclosed opening brackets in the order that you encounter them in, and removing them whenever you encounter a closing bracket, as a sort of stack.
This solution has a complexity of O(n).
A problem with this implementation is that there is an unknown amount of brackets in string, which may cause the array to overflow if it isn't large enough.
Solution:
To be sure that this solution doesn't overflow, the size of the array should be at least half the size of the input string, and you'll have to check at each character if there are enough characters left in the input string to be able to completely close all brackets.
Use a list implementation (or write your own) instead of an array for unclosed.
If its ok for you to use stdlib.h then,
#include <stdio.h>
#include <stdlib.h>
#define bool int
// structure of a stack node
struct sNode {
char data;
struct sNode* next;
};
// Function to push an item to stack
void push(struct sNode** top_ref, int new_data);
// Function to pop an item from stack
int pop(struct sNode** top_ref);
// Returns 1 if character1 and character2 are matching left
// and right Brackets
bool isMatchingPair(char character1, char character2)
{
if (character1 == '(' && character2 == ')')
return 1;
else if (character1 == '{' && character2 == '}')
return 1;
else if (character1 == '[' && character2 == ']')
return 1;
else
return 0;
}
// Return 1 if expression has balanced Brackets
bool areBracketsBalanced(char exp[])
{
int i = 0;
// Declare an empty character stack
struct sNode* stack = NULL;
// Traverse the given expression to check matching
// brackets
while (exp[i])
{
// If the exp[i] is a starting bracket then push
// it
if (exp[i] == '{' || exp[i] == '(' || exp[i] == '[')
push(&stack, exp[i]);
// If exp[i] is an ending bracket then pop from
// stack and check if the popped bracket is a
// matching pair*/
if (exp[i] == '}' || exp[i] == ')'
|| exp[i] == ']') {
// If we see an ending bracket without a pair
// then return false
if (stack == NULL)
return 0;
// Pop the top element from stack, if it is not
// a pair bracket of character then there is a
// mismatch.
// his happens for expressions like {(})
else if (!isMatchingPair(pop(&stack), exp[i]))
return 0;
}
i++;
}
// If there is something left in expression then there
// is a starting bracket without a closing
// bracket
if (stack == NULL)
return 1; // balanced
else
return 0; // not balanced
}
// Driver code
int main()
{
char exp[100] = "{()}[]";
// Function call
if (areBracketsBalanced(exp))
printf("Balanced \n");
else
printf("Not Balanced \n");
return 0;
}
// Function to push an item to stack
void push(struct sNode** top_ref, int new_data)
{
// allocate node
struct sNode* new_node
= (struct sNode*)malloc(sizeof(struct sNode));
if (new_node == NULL) {
printf("Stack overflow n");
getchar();
exit(0);
}
// put in the data
new_node->data = new_data;
// link the old list off the new node
new_node->next = (*top_ref);
// move the head to point to the new node
(*top_ref) = new_node;
}
// Function to pop an item from stack
int pop(struct sNode** top_ref)
{
char res;
struct sNode* top;
// If stack is empty then error
if (*top_ref == NULL) {
printf("Stack overflow n");
getchar();
exit(0);
}
else {
top = *top_ref;
res = top->data;
*top_ref = top->next;
free(top);
return res;
}
}
Features
Support nested parantheses like (())
Support bad nestings such as ([)]
Commented but not by me (see the below spoiler)
Note: i feel guilty that i have copied code from here
The algorithm
Pseudocode Like Block code!
If it's not ok for you to use stdlib.h,then someone may edit this code and remove the errors that occur when we remove that line(#include <stdlib.h>),I am not a c guy and i don't know to edit,i just copy pasted !
First attempt didn't worked with bad nesting, as MOehm wrote in the comments.
Storing the opened braces that not have been closed yet helps to recognize bad nesting. The last opened brace will determine which closing brace is need.
#include <stdio.h>
int check(char str[], int size)
{
char opened[size/2];
char close;
int i = 0;
int pos = 0;
int error = 0;
while((i < size) || (pos < size/2))
{
if((str[i] == '(') || (str[i] == '['))
{
opened[pos] = str[i];
pos++;
}
else if((str[i] == ')') || (str[i] == ']'))
{
if(str[i] == close)
{
opened[pos-1] = 0;
pos--;
}
else
{
error = 1;
break;
}
}
printf("%s\n", opened);
if(pos > 0)
{
switch(opened[pos-1])
{
case '(':
close = ')';
break;
case '[':
close = ']';
break;
}
}
else
close = 0;
i++;
}
return error;
}
int main() {
char str[20];
printf("%d\n", check(str, sizeof(str)));
return 0;
}

semantical error with parenthesis balancing here

I've written a C code to check for simple parenthesis balancing which prints NO and YES if balanced, not balanced respectively.
The problem is that I'm getting NO for all inputs. Hence I'm thinking that its a semantic error but cannot find it (I have been trying for 2 days :p)
Could someone please help me here? thanks!
#include <stdio.h>
#include <stdlib.h>
typedef struct stack {
char s[1000];
int top;
} STACK;
void create(STACK *sptr) {
sptr->top = -1;
}
int isEmpty(STACK *sptr) {
if (sptr->top == -1)
return 1;
else
return 0;
}
void push(STACK *sptr, char data) {
sptr->s[++sptr->top] = data;
}
char pop(STACK *sptr) {
if (isEmpty(sptr) == 0)
return sptr->s[sptr -> top];
else
return '$';
}
char *isBalanced(char *s, STACK *sptr) {
char *y, *n;
int i = 0;
y = (char*)malloc(sizeof(char) * 4);
y[0] = 'Y';
y[1] = 'E';
y[2] = 'S';
y[3] = '\0';
n = (char*)malloc(sizeof(char) * 3);
n[0] = 'N';
n[1] = 'O';
n[2] = '\0';
while (s[i] != '\0') {
if (s[i] == '(' || s[i] == '{' || s[i] == '[') {
push(sptr, s[i]);
} else {
char x = pop(sptr);
switch (s[i]) {
case ')':
if (x != '(')
return n;
break;
case '}':
if (x != '{')
return n;
break;
case ']':
if (x != '[')
return n;
break;
}
}
++i;
}
if (isEmpty(sptr))
return y;
else
return n;
}
int main() {
STACK *sptr = (STACK *)malloc(sizeof(STACK));
char c[21];
int ch;
do {
printf("enter sequence:");
scanf("%s", c);
char *msg = isBalanced(c, sptr);
printf("%s", msg);
printf("choice?:");
scanf("%d", &ch);
} while(ch);
}
updated code:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack {
char s[1000];
int top;
} STACK;
void create(STACK *sptr) {
sptr->top = -1;
}
int isEmpty(STACK *sptr) {
if (sptr->top == -1)
return 1;
else
return 0;
}
void push(STACK *sptr, char data) {
sptr->s[++sptr->top] = data;
}
char pop(STACK *sptr) {
if (isEmpty(sptr) == 0)
return sptr->s[sptr->top--];
else
return '$';
}
int isBalanced(char *s, STACK *sptr) {
int i = 0;
while (s[i] != '\0') {
if (s[i] == '(' || s[i] == '{' || s[i] == '[') {
push(sptr, s[i]);
} else {
char x = pop(sptr);
switch (s[i]) {
case ')':
if (x != '(')
return 0;
break;
case '}':
if (x != '{')
return 0;
break;
case ']':
if (x != '[')
return 0;
break;
}
}
++i;
}
if (isEmpty(sptr))
return 1;
else
return 0;
}
int main() {
STACK *sptr = malloc(sizeof(STACK));
char c[21];
int ch;
do {
printf("enter sequence:");
scanf("%s", c);
printf("%s", (isBalanced(c, sptr) ? "YES" : "NO"));
printf("choice?:");
scanf("%d", &ch);
} while(ch);
}
Here are some major issues in your code:
you do not properly initialize the stack with create(sptr) before use, preferably in main() where it is defined. Your code has undefined behavior. It prints NO by chance, probably because sptr->top has an initial value of 0, which makes the stack non-empty.
you should only pop from the stack when you encounter a closing delimiter ), ] or }.
you should prevent potential buffer overflow by telling scanf() the maximum number of characters to read into c: scanf("%20s", c). Furthermore you should test the return value to avoid undefined behavior at end of file.
Note also that the STACK can be made a local variable to avoid heap allocation and potential allocation failure, which would cause undefined behavior since it is not tested.
Here is a corrected version:
#include <stdio.h>
typedef struct stack {
char s[1000];
int top;
} STACK;
void create(STACK *sptr) {
sptr->top = -1;
}
int isEmpty(STACK *sptr) {
if (sptr->top == -1)
return 1;
else
return 0;
}
void push(STACK *sptr, char data) {
sptr->s[++sptr->top] = data;
}
char pop(STACK *sptr) {
if (isEmpty(sptr) == 0)
return sptr->s[sptr->top--];
else
return '$';
}
int isBalanced(char *s, STACK *sptr) {
int i;
for (i = 0; s[i] != '\0'; i++) {
switch (s[i]) {
case '(':
case '{':
case '[':
push(sptr, s[i]);
break;
case ')':
if (pop(sptr) != '(')
return 0;
break;
case '}':
if (pop(sptr) != '{')
return 0;
break;
case ']':
if (pop(sptr) != '[')
return 0;
break;
}
}
return isEmpty(sptr);
}
int main() {
STACK s, *sptr = &s;
char c[100];
int ch;
do {
printf("Enter sequence: ");
if (scanf(" %99[^\n]", c) != 1)
break;
create(sptr);
printf("%s\n", isBalanced(c, sptr) ? "YES" : "NO");
printf("Choice? ");
if (scanf("%d", &ch) != 1)
break;
} while (ch);
return 0;
}
In your pop function you are not decrementing the top thus your isEmpty function always returns false.
Hence you return no always.
char* isBalanced(char* s, STACK* sptr)
{
....
if(isEmpty(sptr)) return y;
else return n;
}
The following is the correct implementation:
char pop(STACK* sptr)
{
if(isEmpty(sptr) == 0)
return sptr->s[sptr->top--];
else
return '$';
}
I assume that the idea is this: an opening paren is always permitted (in the analyzed text), but a closing paren must match the last opened. This is why a stack is required. Also, in the end, if the stack is not empty that means that some parens were not closed.
So, you should use the stack, but only when you encounter parens - either opening or closing.
In the function isBalanced(), the main cycle could be this:
while (s[i] != '\0') {
if ( s[i] == '(' || s[i] == '{' || s[i] == '[' ) {
// opening - remember it
push(sptr, s[i]);
} else if ( s[i] == ')' || s[i] == '}' || s[i] == ']' ) {
// closing - it should match
if ( ! popmatch(sptr, s[i]) )
return n;
}
++i;
}
The rest of the function is ok. Now, I modified the the pop() function: renamed to popmatch, because it should check if the argument matches the top of the stack. If it does, pop the stack and return OK. So the function would be:
char popmatch(STACK* sptr, char c) {
// an empty stack can not match
if (isEmpty(sptr))
return 0;
// not empty, can check for equality
if ( c =! sptr->s[sptr->top] )
return 0;
// does not match!
// ok, it matches so pop it and return ok
sptr->top--;
return 1;
}
Please note that the code mirrors pretty well the "analysis"; when the analysis is short and clear, and the code follows the analysis, the result often is short and clear too.
I would add the flags to see which one does not match
unsigned match(const char *f)
{
int p = 0,s = 0,b = 0;
while(*f)
{
switch(*f++)
{
case '(':
p++;
break;
case ')':
p -= !!p;
break;
case '[':
s++;
break;
case ']':
s -= !!s;
break;
case '{':
b++;
break;
case '}':
b -= !!b;
break;
default:
break;
}
}
return (!p) | ((!s) << 1) | ((!b) << 2);
}
Not the stack version but just for the idea. It is rather easy to add push and pop

Count word in string

I'm trying to write a function to count occurrences of a particular word in a string. For example: Given string -
"Stop, time to go home. Todo fix me."
Letters "to" appeared three times (twice in different words); however, the word "to" appears only once. What should I do to count only word "to" (if will appear in string more times then count every single one). Any advice?
This is the code I was trying and playing around.
int word(char inputLine[]) {
int word = 0, i = 0, j = 0;
for (i = 0; inputLine[i] != '\0'; i++) {
if (inputLine[i] == 't' || inputLine[i] == 'o' || inputLine[i] != ' ') {
word++;
}
}
return word;
}
Try this:
int word(char inputLine[]) {
int word = 0, i = 0;
// stop before the last char
for (i = 0; inputLine[i] != '\0' && inputLine[i+1] != '\0'; i++) {
// is (T or t) and (O or o)
if ((inputLine[i] == 't' || inputLine[i] == 'T') && (inputLine[i+1] == 'o' || inputLine[i+1] == 'O')) {
// after the 'to' is not a letter
if ((inputLine[i+2] < 'a' || inputLine[i+2] > 'z') &&
(inputLine[i+2] < 'A' || inputLine[i+2] > 'Z')) {
// before is not a letter (or this is the start of the string)
if (i == 0 ||
((inputLine[i-1] < 'a' || inputLine[i-1] > 'z') &&
(inputLine[i-1] < 'A' || inputLine[i-1] > 'Z'))) {
word++;
}
}
}
}
return word;
}
The simplest way would be to use strtok. But, if you'd like to do it all by hand, the following will work. Although you only wanted the "to" this will work for any search string:
#include <stdio.h>
// word -- get number of string matches
int
word(char *input,char *str)
// input -- input buffer
// str -- string to search for within input
{
int chr;
int prev;
int off;
int stopflg;
int wordcnt;
off = -1;
stopflg = 0;
wordcnt = 0;
prev = 0;
for (chr = *input++; ! stopflg; prev = chr, chr = *input++) {
// we've hit the end of the buffer
stopflg = (chr == 0);
// convert whitespace characters to EOS [similar to what strtok might
// do]
switch (chr) {
case ' ':
case '\t':
case '\n':
case '\r':
chr = 0;
break;
}
++off;
// reset on mismatch
// NOTE: we _do_ compare EOS chars here
if (str[off] != chr) {
off = -1;
continue;
}
// we just matched
// if we're starting the word we must ensure we're not in the middle
// of one
if ((off == 0) && (prev != 0)) {
off = -1;
continue;
}
// at the end of a word -- got a match
if (chr == 0) {
++wordcnt;
off = -1;
continue;
}
}
return wordcnt;
}
void
tryout(int expcnt,char *buf)
{
int actcnt;
actcnt = word(buf,"to");
printf("%d/%d -- '%s'\n",expcnt,actcnt,buf);
}
// main -- main program
int
main(int argc,char **argv)
{
char *cp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
default:
break;
}
}
tryout(1,"to");
tryout(2,"to to");
tryout(1," to ");
tryout(1,"todo to");
tryout(2,"todo to to");
tryout(2,"doto to to");
tryout(1,"doto to doto");
tryout(0,"doto");
return 0;
}
If you must use only "basic" C functions the above solutions seems ok, but in the case you want to build a more scalable application (and you want to solve the problem in a smarter way) you can use a library that manipulate regular expressions. You can check this answer: Regular expressions in C: examples?
Regexes has the advantage that you can make the regex case unsensible (That is one of your issues).
I usually use pcre because it has the regex style of perl and java.
Here it is a very useful example that uses pcre: http://www.mitchr.me/SS/exampleCode/AUPG/pcre_example.c.html
Let's posit these rules:
"to" can be a word only when there is no char before and after it except the space char
If you accept those rules as valid and correct you need to check 4 conditions:
if (str[i]=='t'&& str[i+1]=='o'&& str[i-1]!='a-z'&& str[i+2]!='a-z'){
word++;
}
Two more conditions can be included to check for the upper case letters.
public class FindCountOfWordInString {
public static void main(String[] args) {
String str = "yhing ghingu jhhtring inghfg ajklingingd me";
String find = "ing";
int count = findCountOfWordInString(str, find);
System.out.println(count);
}
private static int findCountOfWordInString(String str, String find) {
String[] strArr = str.split(" ");
int count = 0, k = 0;
for (int i = 0; i < strArr.length; i++) {
if (strArr[i].contains(find)) {
String strCheck = strArr[i];
char[] findCharArr = find.toCharArray();
for (int j = 0; j < strCheck.length(); j++) {
if (strCheck.charAt(j) == findCharArr[k]) {
k++;
if (k == 3) {
count++;
k = 0;
}
} else {
k = 0;
}
}
}
}
return count;
}
}

Seriously What's wrong in my code

I am trying to solve one problem from spoj http://www.spoj.com/problems/ARITH2/
But every time i am getting 'WA' Wrong Answer.I've tried every possible Test Case and it's giving me expected results.I've written the code mentioned below:
#include <stdio.h>
int main() {
int t,s=0;char operator;
scanf("%d",&t);
while(t--)
{
signed long long int s=0,c=0;
scanf("%lld",&s);
while(1)
{
operator=0;
operator=getc(stdin);
if(operator=='=')
break;
scanf("%lld",&c);
switch(operator)
{
case '+' : s=s+c;
break;
case '-' : s=s-c;
break;
case '*' : s=s*c;
break;
case '/' : s=s/c;
break;
}
}
printf("%lld\n",s);
}
return 0;
}
Please check the requirement, you should not use scanf instead, using sscanf cos the input is whole expression such 50 * 40 * 250 + 791 =. You can create a simple parser as below code to walkthrough whole expression.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char ch = 0;
int state = 0;
char buff[128];
char ops = 0;
unsigned int result = 0;
int i = 0, idx = 0;
char expr[1024];
int cnt = 0;
if (scanf("%[^=]=%n", expr, &cnt) <= 0)
return 0;
while(idx < cnt) {
ch = expr[idx++];
printf("state %d ch %c\n", state, ch);
switch(state) {
case 0:
if ((ch <= '9') && (ch >= '0')) {
state++;
buff[i++] = ch;
}
break;
case 1:
if ((ch <= '9') && (ch >= '0')) {
buff[i++] = ch;
} else {
buff[i] = '\0';
if (i > 0) {
unsigned int num = atoi(buff);
switch (ops) {
case '-':
result -= num;
break;
case '+':
result += num;
break;
case '*':
result *= num;
break;
case '/':
result /= num;
break;
default:
result = num;
break;
}
printf("> found fact %d, result %u\n", num, result);
}
i = 0;
if ((ch == '-') || (ch == '+') || (ch == '*') || (ch == '/')) {
state = 0;
ops = ch;
printf("> found ops %c\n", ch);
} else if ((ch == ' ') || (ch == '\t')) {
continue;
} else if (ch == '=') {
break;
} else {
// expression end
break;
}
}
break;
default:
break;
}
}
printf("> result '%u' ", result);
return 0;
}
Quick glance, it doesn't look like you are respecting the spacing outlined in the spec. For example, 1 + 1 * 2 = is going to read the wrong character for operator. 1+1*2= looks like it'll work, but that's not what was asked for.
Also, you're reading in unsigned integers and will instantly fail any test cases with signed numbers.

infix to postfix with white space

I have a program which convert the infix form to postfix form.
example if the input is :(-2+4-(3+3))
then the output is : 2-4+33+-
my expected ouput is : 2 - 4 + 3 3 + -
How should I do to change it , I am thinking somethings like extra 1 more space when I pop() the stack.
Here is the code:
#include <stdio.h>
#include <ctype.h>
#include<string.h>
#define SIZE 50
char s[SIZE];
int top = -1;
void push(char elem) {
s[++top] = elem;
}
char pop() {
return (s[top--]);
}
int pr(char elem) {
switch (elem) {
case '#':
return 0;
case '(':
return 1;
case '+':
case '-':
return 2;
case '*':
case '/':
return 3;
}
}
int main()
{
char infx[50], pofx[50], ch, elem;
int i = 0, k = 0;
printf("\n\nRead the Infix Expression ?");
scanf("%s", infx);
push('#');
while ((ch = infx[i++]) != '\0') {
if (ch=='(')
push(ch);
else if (isalnum(ch))
pofx[k++] = ch;
else if (ch == ')') {
while (s[top] != '(')
pofx[k++] = pop();
elem = pop();
} else {
while (pr(s[top]) >= pr(ch))
pofx[k++] = pop();
push(ch);
}
}
while (s[top] != '#')
pofx[k++] = pop();
pofx[k] = '\0';
printf("\n\nGiven Infix Expn: %s Postfix Expn: %s \n", infx,pofx);
}
Thank you
Well first off, I wasn't able to compile your code due to this line
int top = -1;
void push(char elem) {
s[++top] = elem;
}
It's very dangerous to initialize your arrays using a variable that's negative. When we go to pop() the character symbols in the array, it will return to its initial state at top = -1 which causes the compilation error. My suggestion is to change your code around to something like this, which will lead you to change somethings around with placing characters in your array:
int top = 0;
void push(char elem) {
s[top++] = elem;
}
As for printing your strings with spaces in between each character use something along the lines of:
for (int i = 0, i < stren(infix) + 1; i++)
{
printf ("%c ", infix[i]);
}
// Same goes for the postfix. More of a formatting of the print characters really...

Resources