Line in text file is evaluated multiple times? - c

I need to convert infix to postfix and evaluate postfix expression. When reading from a file, I should be able to evaluate multiple expressions at once. But when I run it and it encounters an expression that is not well-formed in the sense that there are more closed parentheses than open ones, it evaluates that expression 2 or 3 times.
Code:
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1000
typedef struct stack
{
int data[MAX];
int top;
} stack;
int priority(char);
void init(stack*);
int empty(stack*);
int full(stack*);
char pop(stack*);
void push(stack*, char);
char top(stack*);
void add(char*, char, int);
void keyboard();
void read_file();
int change(char);
void pushYO(double);
double popYO();
stack s;
char x;
int i, token, topYO = -1;
double result[MAX];
char filepath[MAX];
int main()
{
char choice;
init(&s);
system("CLS");
printf("[1] Keyboard \n[2] Read from text file \n[3] Exit \n");
scanf("%c", &choice);
if(choice != '1' && choice != '2' && choice != '3')
{
main();
}
else if(choice == '1')
{
keyboard();
}
else if(choice == '2')
{
read_file();
}
else if(choice == '3')
{
printf("\nThank you for using Kei Shirabe's \ninfix to postfix converter and evaluator! :)\n");
exit(0);
}
}
void keyboard() //the keyboard input version. this works fine
{
//code here
}
void read_file()
{
int z, count, form, paren;
double one, two, three = 1;
char infx[MAX];
char pofx[MAX];
char choice;
FILE *text = fopen("text.txt", "a");
printf("Enter path of file:");
scanf("%s",&filepath);
FILE *textYO = fopen(filepath, "r");
if((textYO) == NULL)
{
printf("\nError! Unable to open %s\n\n", filepath);
}
else
{
while((fgets(infx, MAX, textYO))!= NULL)
{
form = -1, paren = 0, count = 0, z = 0;
infx[
strlen(infx)-1] = '\0';
for (i=0; i<strlen(infx); i++)
{
if((token = infx[i]) != '\n')
{
if(isalnum(token))
{
form++;
}
else
{
if(token == '(')
{
paren++;
}
else if(token == ')')
{
paren--;
}
else
{
form--;
}
}
if (paren < 0)
{
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nError! Not well formed :( \n-----------------\n");
fprintf(text, "\n\nError! Not well formed :( \n-----------------\n");
}
else
if(isalnum(token))
{
add(pofx, token, count);
count++;
}
else
if(token == '(')
{
push(&s, '(');
}
else
{
if(token == ')')
while((x = pop(&s)) != '(')
{
add(pofx, x, count);
count++;
}
else
if(token == '^')
{
push(&s, token);
}
else
{
while(priority(token) <= priority(top(&s)) && !empty(&s))
{
x = pop(&s);
add(pofx, x, count);
count++;
}
push(&s, token);
}
}
}
else
{
while(!empty(&s))
{
x = pop(&s);
add(pofx, x, count);
count++;
}
}
}
if(form != 0 || paren != 0)
{
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nError! Not well formed :( \n-----------------\n");
fprintf(text, "\n\nError! Not well formed :( \n-----------------\n");
}
else
{
form = -1, paren = 0;
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nPostfix: %s \n\n", pofx);
fprintf(text, "\n\nPostfix: %s\n\n", pofx);
while((token = pofx[z++]) != '\0')
{
three = 1;
if(!isdigit(token) && !isalpha(token))
{
two = popYO();
one = popYO();
switch(token)
{
case '+':
pushYO(one+two); break;
case '-':
pushYO(one-two); break;
case '*':
pushYO(one*two); break;
case '/':
pushYO(one/two); break;
case '^':
if (two > 0)
{
for(i=0;i<two;i++)
{
three = three * one;
}
pushYO(three);
three = 1; break;
}
else
{
for(i=0;i<(two-(2*two));i++)
{
three = three * one;
}
pushYO((1/three));
three = 1; break;
}
}
}
else if(isalpha(token))
{
if(isupper(token))
{
pushYO(token - '#');
}
if(islower(token))
{
pushYO(token - change(token));
}
}
else
{
pushYO(token - '0');
}
}
printf("Result: %lf\n-----------------\n", result[topYO]);
fprintf(text, "Result: %lf\n-----------------\n", result[topYO]);
}
}
}
fclose(text);
fclose(textYO);
printf("\nRun again? \n[1] Yes \n[any other key] No\n");
scanf("%c", &choice);
scanf("%c", &choice);
if(choice == '1')
{
main();
}
else
{
printf("\nThank you for using Kei Shirabe's \ninfix to postfix converter and evaluator! :)\n");
exit(0);
}
}
//other functions down here, not important
Sample text file (and yes there is an extra space at the end):
(1+2))
(1+2*3)
For this text file, the expression (1+2)) is evaluated three times, each result being "Not well formed". The last expression works as expected.
Any help please?

Related

I am doing a mini project on stack applications, and get errors

The program:
evaluates postfix and prefix expressions
reverse a string
parenthesis balancing
decimal to binary conversion
infix to postfix conversion
There a some extra characters (emojis) appended in the output. I would like to fix that.
Also I have used two pop functions with int and char return type how can I reduce it to one single function.
extra characters in the output of decimal to binary conversion, also that one extra left parenthesis when printing "balanced parenthesis"
This a first year college project.
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
int stack[MAX], opp1, opp2, top = -1;
struct stack
{
char stck[20];
int top;
}
s;
void push(int x)
{
top++;
stack[top] = x;
}
int pop()
{
char c;
c = stack[top];
top = top - 1;
printf("%c", c);
}
char pop1()
{
if (top == -1)
return -1;
else
return stack[top--];
}
void postfixeval()
{
char postfix[20];
int res, i;
gets(postfix);
for (i = 0; postfix[i] != '\0'; i++)
{
if (isdigit(postfix[i]))
{
push(postfix[i] - 48);
}
else
{
opp2 = pop();
opp1 = pop();
switch (postfix[i])
{
case '+':
push(opp1 + opp2);
break;
case '-':
push(opp1 - opp2);
break;
case '*':
push(opp1 *opp2);
break;
case '/':
push(opp1 / opp2);
break;
case '^':
res = pow(opp1, opp2);
break;
}
}
}
printf("result is %d \n", pop());
}
void prefixeval()
{
int len;
char prefix[20];
int res, i;
gets(prefix);
len = strlen(prefix);
for (i = len - 1; i >= 0; i--)
{
if (isdigit(prefix[i]))
{
push(prefix[i] - 48);
}
else
{
opp1 = pop();
opp2 = pop();
switch (prefix[i])
{
case '+':
push(opp1 + opp2);
break;
case '-':
push(opp1 - opp2);
break;
case '*':
push(opp1 *opp2);
break;
case '/':
push(opp1 / opp2);
break;
case '^':
res = pow(opp1, opp2);
push(res);
break;
}
}
}
printf("result is %d \n", pop());
}
int match(char a, char b)
{
if (a == '[' && b == ']')
return 1;
if (a == '{' && b == '}')
return 1;
if (a == '(' && b == ')')
return 1;
}
int check(char exp[])
{
int i;
char temp;
for (i = 0; i < strlen(exp); i++)
{
if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
push(exp[i]);
if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']')
if (top == -1)
{
return 0;
}
else
{
temp = pop();
if (!match(temp, exp[i]))
{
printf("Mismatched parentheses are : ");
printf("%c and %c\n", temp, exp[i]);
return 0;
}
}
}
if (top == -1)
{
printf("Balanced Parentheses\n");
return 1;
}
else
{
return 0;
}
}
void dectobin(int n)
{
while (n != 0)
{
push(n % 2);
n = n / 2;
}
while (top != -1)
{
printf("%d", pop());
}
}
int priority(char x)
{
if (x == '(')
return 0;
if (x == '+' || x == '-')
return 1;
if (x == '*' || x == '/')
return 2;
}
void intopost()
{
char exp[100];
char *e, x;
printf("Enter the expression : \n");
scanf("%s", exp);
printf("\n");
e = exp;
while (*e != '\0')
{
if (isalnum(*e))
printf("%c ", *e);
else if (*e == '(')
push(*e);
else if (*e == ')')
{
while ((x = pop1()) != '(')
printf("%c ", x);
}
else
{
while (priority(stack[top]) >= priority(*e))
printf("%c ", pop1());
push(*e);
}
e++;
}
while (top != -1)
{
printf("%c ", pop1());
}
}
int main()
{
int ch, i, len;
char postfix[20], prefix[20], str[30];
do {
printf("\n----STACK APPLICATIONS----\n");
printf("1.postfix expression evaluation\n2.prefix expression evaluation\n3.reverse a string\n4.paranthesis balancing\n5.decimal to binary\n6.infix to postfix\n7.exit\n");
printf("enter choice");
scanf("%d", &ch);
switch (ch)
{
case 1:
{
printf("enter postfix expression\n");
scanf("%c", &postfix);
postfixeval();
break;
}
case 2:
{
printf("enter prefix expression\n");
scanf("%c", prefix);
prefixeval();
break;
}
case 3:
{
printf("enter string\n");
scanf("%s", str);
len = strlen(str);
for (i = 0; i < len; i++)
{
push(str[i]);
}
printf("reversed string is:");
for (i = 0; i < len; i++)
{
pop();
}
break;
}
case 4:
{
char exp[20];
int valid;
printf("Enter an algebraic expression : \n");
scanf("%s", exp);
valid = check(exp);
if (valid == 1)
{
printf("Valid expression\n");
}
else
{
printf("Invalid expression\n");
}
break;
}
case 5:
{
int dec;
printf("enter decimal number\n");
scanf("%d", &dec);
dectobin(dec);
break;
}
case 6:
{
intopost();
break;
}
case 7:
{
exit(0);
}
default:
printf("invalid choice\n");
}
} while (ch != 7);
}
Here are the additional characters appended with the output
Here is one 'improvement' that you should learn about 'C'.
printf(
"1.postfix expression evaluation\n"
"2.prefix expression evaluation\n"
"3.reverse a string\n"
"4.paranthesis balancing\n"
"5.decimal to binary\n"
"6.infix to postfix\n"
"7.exit\n"
);
The compiler will 'join-up' those 'segments' (because there is no comma between a close quote and the next open quote.)
Once you have that, you can go back to basics and get this much displaying and functioning:
printf(
// "1.postfix expression evaluation\n"
// "2.prefix expression evaluation\n"
// "3.reverse a string\n"
// "4.paranthesis balancing\n"
// "5.decimal to binary\n"
// "6.infix to postfix\n"
"7.exit\n"
);
Don't try to run before you can walk...
To demonstrate 'incremental development' and 'learning/exploring':
// test.c - string segments in source code
#include <stdio.h>
int main() {
printf(
"Hello "
"World!\n"
);
return 0;
}

why this program ends when i type the first word and doesn't loop back

i want to make the programm loop again and again until i type the endword ****TELOS
/* 1 */ int text_input();
int main() {
int number;
text_input();
return 0;
}
int text_input(char words[M][N]){
int l=0; /*lines, also how many words the text has */
char a;
int i=0;
printf("Enter the text. (****TELOS for stoping)");
char endword[10];
strcpy(endword, "****TELOS");
char temp[N];
while(1){
while(1) {
a = getchar();
if (a =='\n'){
if(strcmp(temp, "") == 0){
continue;
}
else{
break;
}
}
else if (a == ' '){
if(strcmp(temp, "") == 0){
continue;
}
else{
break;
}
}
else {
temp[i++] = a;
}
}
if (strcmp(temp, endword) == 0){
break;
}
else{
strcpy(words[l++],temp);
memset(temp, ' ', strlen(temp));
}
}
return 0;
}
I think your code doesn't work because you don't have set each item of endword to 0
so your code should be like that
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 10
#define M 10
int text_input(char words[M][N]);
int main() {
char a[M][N];
text_input(a);
return 0;
}
int text_input(char words[M][N]){
int l=0; /*lines, also how many words the text has */
char a;
int i=0;
char temp[N];
char endword[10] = {0,0,0,0,0,0,0,0,0,0};
printf("Enter the text. (****TELOS for stoping)");
strcpy(endword, "****TELOS");
while(1){
while(1) {
a = getchar();
if (a =='\n'){
if(strcmp(temp, "") == 0){
continue;
}
else{
break;
}
}
else if (a == ' '){
if(strcmp(temp, "") == 0){
continue;
}
else{
break;
}
}
else {
temp[i++] = a;
}
}
if (strcmp(temp, endword) == 0){
break;
}
else{
strcpy(words[l++],temp);
memset(temp, ' ', strlen(temp));
}
}
return 0;
}

C program which counts lines and operators wrong

This program should read rows and count operators, but counts wrong and can not find out where the errors are.
Help me find out the bugs and fix the program to be able to count rows and operators correctly.I've already tried several ways to fix it and it still counts wrong.
Current output:Broqt na operatorite e:1
Broqt na redovete e:1119
Expected output: Broqt na operatorite e:11
Broqt na redovete e:221
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
void cycleOperatorsCounter(FILE* inputStream, FILE* outputStream);
void counter(FILE* inputStream, FILE* outputStream);
int fileToFile(void);
int fileToScreen(void);
int screenToFile(void);
int screenToScreen(void);
void getFileName(char* fileName, int mode);
int menu() {
int i;
printf("----1. FILE TO FILE \n");
printf("----2. FILE TO SCREEN \n");
printf("----3. KBRD TO FILE \n");
printf("----4. KBRD TO SCREEN \n");
printf("----0. EXIT \n");
do {
printf("SELECT OPTION: ");
fflush(stdin);
scanf("%i", &i);
} while (i < 0 || i> 4);
return i;
}
int main(void) {
while (1) {
system("cls");
switch (menu()) {
case 1: fileToFile();
break;
case 2: fileToScreen();
break;
case 3: screenToFile();
break;
case 4: screenToScreen();
break;
default:
return 0;
}
system("pause");
}
}
void getFileName(char* fileName, int mode) {
while (1) {
fflush(stdin);
if (mode == 1) {
printf("Input file name(.C): ");
gets(fileName);
if (fileName[strlen(fileName) - 2] == '.' && toupper(fileName[strlen(fileName) - 1]) == 'C') {
return;
}
}
else {
printf("Output File: ");
gets(fileName);
return;
}
}
}
int fileToFile(void) {
char inputFileName[256], outputFileName[256];
FILE *inputStream, *outputStream;
getFileName(inputFileName, 1);
if (!(inputStream = fopen(inputFileName, "r"))) {
fprintf(stderr, "Error opening file!\n");
return -1;
}
getFileName(outputFileName, 2);
if (!(outputStream = fopen(outputFileName, "w"))) {
fprintf(stderr, "Error opening file!\a\n");
return -1;
}
cycleOperatorsCounter(inputStream, outputStream);
rewind(inputStream);
counter(inputStream, outputStream);
fclose(inputStream);
fclose(outputStream);
printf("Results saved to \"%s\".\n", outputFileName);
return 0;
}
int fileToScreen(void) {
char inputFileName[256];
FILE* inputStream;
getFileName(inputFileName, 1);
if (!(inputStream = fopen(inputFileName, "r"))) {
fprintf(stderr, "Error opening file!\n");
return -1;
}
cycleOperatorsCounter(inputStream, stdout);
rewind(inputStream);
counter(inputStream, stdout);
fclose(inputStream);
return 0;
}
int screenToFile(void) {
char outputFileName[256];
FILE *outputStream, *tempStream;
char str[999];
tempStream = fopen("temp.tmp", "w");
fflush(stdin);
printf("Napishete \"KRAI\" na nov red, kogato vuvedete teksta\n");
while (1) {
gets(str);
if (!strcmp(str, "KRAI")) {
fclose(tempStream);
tempStream = fopen("temp.tmp", "r");
break;
}
fprintf(tempStream, "%s\n", str);
}
getFileName(outputFileName, 2);
if (!(outputStream = fopen(outputFileName, "w"))) {
fprintf(stderr, "Error opening file!\a\n");
return -1;
}
cycleOperatorsCounter(tempStream, outputStream);
rewind(tempStream);
counter(tempStream, outputStream);
fclose(tempStream);
fclose(outputStream);
printf("Results saved to \"%s\".\n", outputFileName);
return 0;
}
int screenToScreen(void) {
FILE *tempStream;
char str[999];
tempStream = fopen("temp.tmp", "w");
fflush(stdin);
printf("Napishete \"KRAI\" na nov red, kogato vuvedete teksta\n");
while (1) {
gets(str);
if (!strcmp(str, "KRAI")) {
fclose(tempStream);
tempStream = fopen("temp.tmp", "r");
break;
}
fprintf(tempStream, "%s\n", str);
}
cycleOperatorsCounter(tempStream, stdout);
rewind(tempStream);
counter(tempStream, stdout);
fclose(tempStream);
return 0;
}
void cycleOperatorsCounter(FILE* inputStream, FILE* outputStream) {
char str[1000];
int cycleCounter = 0;
unsigned i;
while (fgets(str, sizeof(str), inputStream) != NULL) {
for (i = 0; i < strlen(str); i++) {
if ((str[i-1] == ' ' || str[i-1] == '\n' || str[i-1] == '\t' || i==0) &&
(str[i] == 'i') && (str[i + 1] == 'f') && (str[i+3] == ' ' || str[i+3] ==
'\n' || str[i+3] == '\t')) {
cycleCounter++;
}
if ((str[i-1] == ' ' || str[i-1] == '\n' || str[i-1] == '\t' ||
i==0)
&& (str[i] == 'e') && (str[i + 1] == 'l') && (str[i + 2] == 's')
&& (str[i + 3] == 'e')
&& (str[i+5] == ' ' || str[i+6] == '\n' || str[i+7] ==
'\t')) {
cycleCounter++;
}
}
}
fprintf(outputStream, "Broqt na operatorite za cikul e: %d\n",
cycleCounter);
}
void counter(FILE* inputStream, FILE* outputStream) {
char str[1000];
int Counter = 0;
unsigned i;
while (fgets(str, sizeof(str), inputStream) != NULL) {
for (i = 0; i < strlen(str); i++) {
{
if ((str[i-1] == ' ' || str[i-1] == '\n' || str[i-1] == '\t' || i==0))
{
Counter++;
}
}
}
}
fprintf(outputStream, "Broqt na redovete e: %d\n", Counter);
}
This is prefaced by my top comments.
That is, finding the if and the else is more easily done with strtok and strcmp.
And, to count rows/lines, simply doing fgets and counting or doing fgetc and counting the \n will work.
Hopefully, this will get you farther:
void
cycleOperatorsCounter(FILE *inputStream, FILE *outputStream)
{
char *bp;
char *tok;
char str[1000];
int cycleCounter = 0;
while (fgets(str, sizeof(str), inputStream) != NULL) {
bp = str;
while (1) {
tok = strtok(bp," \t\n");
if (tok == NULL)
break;
bp = NULL;
if (strcmp(tok,"if") == 0) {
cycleCounter++;
continue;
}
if (strcmp(tok,"else") == 0) {
cycleCounter++;
continue;
}
}
}
fprintf(outputStream, "Broqt na operatorite za cikul e: %d\n",
cycleCounter);
}
void
counter(FILE *inputStream, FILE *outputStream)
{
int Counter = 0;
// count number of lines
// NOTE: either of these should work:
#if 1
char str[1000];
while (fgets(str, sizeof(str), inputStream) != NULL)
++Counter;
#else
while (1) {
int chr = fgetc(inputStream);
if (chr == EOF)
break;
if (chr == '\n')
++Counter;
}
#endif
fprintf(outputStream, "Broqt na redovete e: %d\n", Counter);
}

Printing string pointers in c

So, essentially I have two files:
File 1:
//
// main.c
// frederickterry
//
// Created by Rick Terry on 1/15/15.
// Copyright (c) 2015 Rick Terry. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int size (char *g) {
int ofs = 0;
while (*(g+ofs) != '\0') {
++ofs;
}
return ofs;
}
int parse(char *g) {
// Setup
char binaryConnective;
int negated = 0;
// Looking for propositions
int fmlaLength = size(g);
if(fmlaLength == 0) {
return 1;
}
if(fmlaLength == 1) {
if(g[0] == 'p') {
return 1;
} else if (g[0] == 'q') {
return 1;
} else if (g[0] == 'r') {
return 1;
} else {
return 0;
}
}
// Now looking for negated preposition
if(fmlaLength == 2) {
char temp[100];
strcpy(temp, g);
if(g[0] == '-') {
negated = 1;
int negatedprop = parse(g+1);
if(negatedprop == 1) {
return 2;
}
}
}
// Checking if Binary Formula
char arrayleft[50];
char arrayright[50];
char *left = "";
char *right = "";
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
if(fmlaLength != 1 && fmlaLength != 2) {
if(g[0] == '-') {
int negatedBinary = parse(g+1);
if(negatedBinary == 1 || negatedBinary == 2 || negatedBinary == 3) {
return 2;
} else {
return 0;
}
}
int i = 0;
int l = 0;
int p = strlen(g);
for(l = 0; l < strlen(g)/2; l++) {
if(g[l] == '(' && g[p-l-1] == ')') {
i++;
}
}
for(int q = i; q < strlen(g); q++) {
if(g[q] == '(') {
numLeft++;
} else if(g[q] == ')') {
numRight++;
}
arrayleft[q] = g[q];
//printf("%c", arrayleft[i]);
//printf("%s", left);
if((numRight == numLeft) && (g[q+1] == 'v' || g[q+1] == '>' || g[q+1] == '^')) {
arrayleft[q+1] = '\0';
bclocation = q+1;
binaryConnective = g[q+1];
binarypresent = 1;
// printf("The binary connecive is: %c\n", binaryConnective);
break;
}
}
if(binarypresent == 0) {
return 0;
}
int j = 0;
for(int i = bclocation+1; i < strlen(g)-1; i++) {
arrayright[j] = g[i];
j++;
}
arrayright[j] = '\0';
left = &arrayleft[1];
right = &arrayright[0];
//printf("Printed a second time, fmla 1 is: %s", left);
int parseleft = parse(left);
// printf("Parse left result: %d\n", parseleft);
if(parseleft == 0) {
return 0;
}
int parseright = parse(right);
if(parseright == 0) {
return 0;
}
// printf("Parse right result: %d\n", parseleft);
if(negated == 1) {
return 2;
} else {
return 3;
}
}
return 0;
}
int type(char *g) {
if(parse(g) == 1 ||parse(g) == 2 || parse(g) == 3) {
if(parse(g) == 1) {
return 1;
}
/* Literals, Positive and Negative */
if(parse(g) == 2 && size(g) == 2) {
return 1;
}
/* Double Negations */
if(g[0] == '-' && g[1] == '-') {
return 4;
}
/* Alpha & Beta Formulas */
char binaryConnective;
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
bclocation = i+1;
binaryConnective = g[i+1];
binarypresent = 1;
break;
}
}
}
/* Connective established */
if(binaryConnective == '^') {
if(g[0] == '-') {
return 3;
} else {
return 2;
}
} else if(binaryConnective == '>') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
} else if (binaryConnective == 'v') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
}
}
return 0;
}
char bin(char *g) {
char binaryConnective;
char arrayLeft[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
int j = 0;
arrayLeft[j++] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[i+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
return binaryConnective;
}
}
}
return binaryConnective;
}
char *partone(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
for(int k = bclocation+1; k < strlen(g)-1; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
int k = 0;
k++;
return leftSide;
}
char *parttwo(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
int n = size(g) - 1;
if(g[strlen(g)-1] != ')') {
n++;
}
for(int k = bclocation+1; k < n; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
char* rightSide = &arrayRight[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
return rightSide;
}
char *firstexp(char *g) {
char* left = partone(g);
char leftArray[50];
int i = 0;
for(i; i < strlen(left); i++) {
leftArray[i] = left[i];
}
leftArray[i] = '\0';
char binConnective = bin(g);
int typeG = type(g);
if(typeG == 2) {
if(binConnective == '^') {
return &leftArray;
} else if(binConnective == '>') {
return &leftArray;
}
} else if(typeG == 3) {
if(binConnective == 'v')
return &leftArray;
}
char temp[50];
for(int i = 0; i < strlen(leftArray); i++) {
temp[i+1] = leftArray[i];
}
temp[0] = '-';
char* lefttwo = &temp[0];
if(typeG == 2) {
if(binConnective == 'v') {
return lefttwo;
}
} else if(typeG == 3) {
if(binConnective == '>' || binConnective == '^') {
return lefttwo;
}
}
return "Hello";
}
char *secondexp(char *g) {
// char binaryConnective = bin(g);
// char* right = parttwo(g);
// char rightArray[50];
// int i = 0;
// for(i; i< strlen(right); i++) {
// rightArray[i+1] = right[i];
// }
// rightArray[i] = '\0';
// int typeG = type(g);
// if(type(g) == 2) {
// if(binaryConnective == '^') {
// return &rightArray;
// }
// } else if(type(g) == 3) {
// if(binaryConnective == 'v' || binaryConnective == '>') {
// return &rightArray;
// }
// }
return "Hello";
}
typedef struct tableau tableau;
\
\
struct tableau {
char *root;
tableau *left;
tableau *right;
tableau *parent;
int closedbranch;
};
int closed(tableau *t) {
return 0;
}
void complete(tableau *t) {
}
/*int main(int argc, const char * argv[])
{
printf("Hello, World!\n");
printf("%d \n", parse("p^q"));
printf("%d \n", type("p^q"));
printf("%c \n", bin("p^q"));
printf("%s\n", partone("p^q"));
printf("%s\n", parttwo("p^q"));
printf("%s\n", firstexp("p^q"));
printf("Simulation complete");
return 0;
}*/
File 2:
#include <stdio.h>
#include <string.h> /* for all the new-fangled string functions */
#include <stdlib.h> /* malloc, free, rand */
#include "yourfile.h"
int Fsize = 50;
int main()
{ /*input a string and check if its a propositional formula */
char *name = malloc(Fsize);
printf("Enter a formula:");
scanf("%s", name);
int p=parse(name);
switch(p)
{case(0): printf("not a formula");break;
case(1): printf("a proposition");break;
case(2): printf("a negated formula");break;
case(3): printf("a binary formula");break;
default: printf("what the f***!");
}
printf("\n");
if (p==3)
{
printf("the first part is %s and the second part is %s", partone(name), parttwo(name));
printf(" the binary connective is %c \n", bin(name));
}
int t =type(name);
switch(t)
{case(0):printf("I told you, not a formula");break;
case(1): printf("A literal");break;
case(2): printf("An alpha formula, ");break;
case(3): printf("A beta formula, ");break;
case(4): printf("Double negation");break;
default: printf("SOmewthing's wrong");
}
if(t==2) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
if(t==3) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
tableau tab;
tab.root = name;
tab.left=0;
tab.parent=0;
tab.right=0;
tab.closedbranch=0;
complete(&tab);/*expand the root node then recursively expand any child nodes */
if (closed(&tab)) printf("%s is not satisfiable", name);
else printf("%s is satisfiable", name);
return(0);
}
If you look at the first file, you'll see a method called * firstexp(char * g).
This method runs perfectly, but only if another method called * secondexp(char * g) is commented out.
If * secondexp(char * g) is commented out, then *firstexp runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is -(pvq), second expansion fmla is Hello
((pvq)>-p) is satisfiableProgram ended with exit code: 0
otherwise, if *secondexp is not commented out, it runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is \240L, second expansion fmla is (-
((pvq)>-p) is satisfiable. Program ended with exit code: 0
As you can see, the outputs are completely different despite the same input. Can someone explain what's going on here?
In the commented-out parts of secondexp and in parttwo, you return the address of a local variable, which you shouldn't do.
You seem to fill a lot of ad-hoc sized auxiliary arrays. These have the problem that they might overflow for larger expressions and also that you cannot return them unless you allocate them on the heap with malloc, which also means that you have to free them later.
At first glance, the strings you want to return are substrings or slices of the expression string. That means that the data for these strings is already there.
You could (safely) return pointers into that string. That is what, for example strchr and strstr do. If you are willing to modify the original string, you could also place null terminators '\0' after substrings. That's what strtok does, and it has the disadvantage that you lose the information at that place: If you string is a*b and you modify it to a\0b, you will not know which operator there was.
Another method is to create a struct that stores a slice as pointer into the string and a length:
struct slice {
const char *p;
int length;
};
You can then safely return slices of the original string without needing to worry about additional memory.
You can also use the standard functions in most cases, if you stick to the strn variants. When you print a slice, you can do so by specifying a field width in printf formats:
printf("Second part: '%.*s'\n", s->length, s->p);
In your parttwo() function you return the address of a local variable
return rightSide;
where rightSide is a pointer to a local variable.
It appears that your compiler gave you a warning about this which you solved by making a pointer to the local variabe arrayRight, that may confuse the compiler but the result will be the same, the data in arrayRight will no longer exist after the function returns.
You are doing the same all over your code, and even worse, in the secondexp() function you return a the address of a local variable taking it's address, you are not only returning the address to a local variabel, but also with a type that is not compatible with the return type of the function.
This is one of many probable issues that your code may have, but you need to start fixing that to continue with other possible problems.
Note: enable extra warnings when compiler and listen to them, don't try to fool the compiler unless you know exactly what you're doing.

Stack of strings

Hi i have program here that accept int as value. i wanted to translate it to accept strings in array then. i have read about using struct but i couldnt get into it. i hope someone can help me getting into that without using struct i dont know where to start i want to keep this lines of code.
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
int top = 0;
int *stack = NULL;
int size = 0;
main()
{
int opt, num;
char cont[] = { 'y' };
clrscr();
/* <start Declaring Stack Size { */
printf("Stacking Program");
printf("\n\nData Size: ");
scanf("%d", &size);
printf("\n");
/* } end> */
/* <start Allocates size of stack { */
if(size > 0)
{
stack = malloc(size * sizeof(int));
if(stack == NULL)
{
printf("ERROR: malloc() failed\n");
exit(2);
}
}
else
{
printf("ERROR: size should be positive integer\n");
exit(1);
}
/* } end> */
while((cont[0] == 'y') || (cont[0] == 'Y'))
{
clrscr();
/* <start Main Menu { */
printf("Stacking Program");
printf("\n\nData Size: %d\n\n", size);
printf("MAIN MENU\n1. Pop\n2. Push\n3. Pick\n4. View\nChoose: ");
scanf("%d", &opt);
printf("\n");
switch(opt) {
case 1:
pop();
break;
case 2:
if(top==size)
{
printf("You can't push more data");
}
else
{
printf("Enter data for Stack[%d]: ", top+1);
scanf("%d", &num);
push(num);
}
break;
case 3:
pick();
break;
case 4:
view();
break;
default:
printf("Your choice is not on the list.");
break;
}
/* } end> */
printf("\n\nDo you want continue\(Y\/N\)?");
scanf("%s", &cont[0]);
}
free(stack);
}
pop()
{
int a;
loading();
if(top <= 0)
{
printf("Stack empty.");
return 0;
}
else
{
top--;
a=stack[top];
printf("\(Stack[%d] = %d\) removed.", top+1, a);
}
}
push(int a)
{
stack[top]=a;
top++;
loading();
}
pick()
{
loading();
if(top <= 0)
{
printf("Nothing to display.");
return 0;
}
else
{
printf("\(Stack[%d] = %d\) is the last data.", top, stack[top-1]);
}
}
view()
{
int i;
loading();
if(top <= 0)
{
printf("Nothing to display.");
return 0;
}
else
{
for(i=0;i<top;i++)
{
printf("Stack[%d] = %d\n", i+1, stack[i]);
}
}
}
loading()
{
float i, x;
float load;
int loadarea[] = { 5000, 10000, 15000, 20000, 25000, 30000 };
int percentLoad;
x=0;
load=0;
percentLoad = loadarea[random(5)];
gotoxy(26,11);
printf("[");
for(i=0;i<25;i++)
{
x = i+27;
gotoxy(x, 11);
printf("=");
delay(percentLoad);
gotoxy(51,11);
printf("]");
gotoxy(53,11);
load=(i/25)*104.5;
if(load>100)
load = 100.00;
printf("%.2f\%",load);
}
delay(60000);
for(i=0;i<60;i++) {
printf("\b \b");
}
printf("\n");
}
Easiest way is to convert your stack to store char* instead of int.
char **stack;
stack = malloc( size * sizeof(char*) );
Now, your push operation will accept a char* from some buffer that is storing the string that was just input, duplicate it with strdup, and store that new pointer in the stack.
typedef enum {
STACK_MEM_ERROR = -1,
STACK_FULL = 0,
STACK_OK = 1
} StackStatus;
StackStatus push(const char *str)
{
char *newstr;
if( top >= size ) return STACK_FULL;
newstr = strdup(str);
if( newstr == NULL ) return STACK_MEM_ERROR;
stack[top++] = newstr;
return STACK_OK;
}
When you pop a string, you just get a pointer.
char *pop()
{
if( top == 0 ) return NULL;
return stack[--top];
}
You are responsible for freeing that memory when you are finished with the pointer (by calling free).
char * val;
while( NULL != (val = pop()) )
{
printf( "I popped: %s\n", val );
free(val);
}

Resources