Can you explain this , challenge? - c

well let's see , i have this code of converting NFA automate to DFA ;which is written by me ; and i discovered let's say a "bug" ;
the printf() instruction
which is meant to be like this " printf("",X); " to prevent the bug
has no characters to print on the screen , you can use any argument you want ; even if it has no value .
the problem is when you remove one of these instructions the result turns upside down ( mingled displaying )
challenge is : explain this bug with details !
the bug is in the NFAtoDFA() func line 69 & 75
here's the code :
#include <stdio.h>
#include <string.h>
#define max 50 //maximum number of symbols and states
#define true 1
#define false 0
#define epsilon '~'
char states [max]={'0','1','2','3','4','5','6','7','8','9','W'};
char initState='0';
char symbols[max]={epsilon,'a','b'};
char finalStates[max]={'W'};
char newSymbols[max]={'a','b'};
char newStates[max][max];
int nbrSymbols=3,nbrStates=11,nbrNewStates=0,nbrNewSymbols=0,nfaMaxLength=2,dfaMaxLength=0;
char NFA [max] [max] [max];
char DFA [max] [max] [max];
int mm ;
/** NDAtoDFA of the NFA */
void NDAtoDFA();
char *makeDFAstate (char state[],int c);
char *epClosure (char stat);
char *nextStates (char sta,char symb);
void add_no_rpt (char ss[],char aa[]);
int getCharIndex (char str[],char c);
int accepted (char str[],char toAccept[]) ;
int findDfaState (char str[]);
/*******************************/
/** flag = 0 | 1 */
/** keep ( 0 | 1 ) occurrences of char c in a string */
void del(char str[],char c,int flag);
/******************************/
/** printing Automates */
void shift(int b,int a);
void showNFA();
void showDFA();
int isFinalState(char state[]);
/******************************/
int main()
{
strcpy( NFA[0][0],"17");strcpy( NFA[1][0],"24");strcpy( NFA[2][1],"3");strcpy( NFA[3][0],"6");
strcpy( NFA[4][2],"5");strcpy( NFA[5][0],"6");strcpy( NFA[6][0],"17");strcpy( NFA[7][1],"8");
strcpy( NFA[8][2],"9");strcpy( NFA[9][2],"W");
NDAtoDFA();
}
/******************************************************/
/******************************************************/
void NDAtoDFA()
{
int i,j; char zz[max];
strcpy(newSymbols,symbols); del(newSymbols,epsilon,0);
nbrNewSymbols=strlen(newSymbols);
/** making the first state*/
strcpy(newStates[nbrNewStates++], epClosure(initState) );
/** */
printf("",mm); /** <=== */
for(i=0;i<nbrNewStates;i++)
{
for(j=0;j<nbrNewSymbols;j++)
{
strcpy(DFA[i][j],makeDFAstate(newStates[i],j));
printf("",mm); /** <=== */
if(findDfaState(DFA[i][j])==false) {strcpy(newStates[nbrNewStates++],DFA[i][j]);
if(strlen(DFA[i][j])>dfaMaxLength) dfaMaxLength=strlen(DFA[i][j]);//for printing DFA
}
}
}
showNFA();
printf("\n ");shift(dfaMaxLength,0); printf("[][][]");
printf("\n ");shift(dfaMaxLength,0); printf("|| ||");
printf("\n ");shift(dfaMaxLength,0); printf("|| ||");
printf("\n ");shift(dfaMaxLength,0); printf("|| ||");
printf("\n ");shift(dfaMaxLength,0); printf("|| ||");
printf("\n ");shift(dfaMaxLength,2);printf("[][] [][]");
printf("\n ");shift(dfaMaxLength,2);printf(" \\\\ //");
printf("\n ");shift(dfaMaxLength,2);printf(" \\\\ // ");
printf("\n ");shift(dfaMaxLength,2);printf(" \\\\// ");
printf("\n ");shift(dfaMaxLength,2);printf(" \\/ ");
showDFA();
}
/******************************************************/
/******************************************************/
void add_no_rpt(char ss[],char aa[])
{int i,j;char tt[1];
for (i=0;aa[i]!=0;i++) if(getCharIndex(ss,aa[i])==-1) {tt[0]=aa[i];tt[1]=0;strcat(ss,tt);}
}
/******************************************************/
/******************************************************/
void del(char str[],char c,int flag)
{
char * p,*barrier;
barrier=p=strchr(str,c);
if (flag==1)
{
barrier=p+1; //set the barrier after the first occurrence of c
p=strchr(barrier,c);
}
while (p!=NULL)
{
for (;*p!='\0';p++) *p=*(p+1);
p=strchr(barrier,c);
}
}
/******************************************************/
/******************************************************/
char* nextStates (char sta,char symb)
{ int i,j;
for(i=0;i<nbrStates ;i++) if(sta ==states [i]) break;
for(j=0;j<nbrSymbols;j++) if(symb==symbols[j]) break;
return NFA[i][j];
}
/******************************************************/
/******************************************************/
int accepted (char str[],char toAccept[])
{ int i;
for (i = 0 ; toAccept[i]!=0; i++)
{
if(toAccept[i]==' ') {del(toAccept,toAccept[i],0);if(i!=0) i--;}
if(getCharIndex(symbols,toAccept[i])!=-1 || getCharIndex(str,toAccept[i])==-1) {return false;}
}
return true;
}
/******************************************************/
/******************************************************/
int getCharIndex(char str[],char c)
{
int i;
for (i = 0 ; str[i]!=0; i++) if(str[i]==c) return i;
return -1;
}
/******************************************************/
/******************************************************/
void showNFA()
{int i,j;
printf("\nSYMBOLS: %s\n",symbols);
printf("STATES : %s\n",states);
printf("FINAL STATES : %s\n\n",finalStates);
puts("STATE TRANS.");
printf("\n ");shift(dfaMaxLength+2,4);printf("NFA | ");
for (i = 0; i < nbrSymbols; i++) {printf(" %c", symbols[i]);shift(nfaMaxLength+1,0);}
printf("\n ");shift(dfaMaxLength+2,0);printf("--------");
for (i = 0; i < nbrSymbols; i++) for(j=0;j<nfaMaxLength+3;j++) printf("-"); printf("\n");
for (i = 0; i < nbrStates; i++) {
shift(dfaMaxLength+3,0);
printf(" %c | ",states[i]);
for (j = 0; j < nbrSymbols; j++)
{
if(strcmp(NFA[i][j],"")==0) {printf(" -");shift(nfaMaxLength+1,strlen(NFA[i][j]));}
else {printf(" %s",NFA[i][j]);shift(nfaMaxLength+2,strlen(NFA[i][j]));}
}
printf("\n");
}
}
/******************************************************/
/******************************************************/
void shift(int b,int a)
{int i;
for (i = 0; i < (b-a); i++)printf(" ");
}
/******************************************************/
/******************************************************/
void showDFA()
{int i,j;
printf("\n\n ");shift(dfaMaxLength,5);printf("DFA |");shift(5,0);
for (i = 0; i < nbrNewSymbols; i++) {printf("%c", newSymbols[i]);shift(dfaMaxLength+5,0);}
printf("\n ");for(j=0;j<dfaMaxLength+6;j++)printf("-");
for (i = 0; i < nbrNewSymbols; i++)for(j=0;j<dfaMaxLength+4;j++)printf("-"); printf("\n");
for (i = 0; i<nbrNewStates; i++) {
if (isFinalState(newStates[i])==true)
if (i==0) printf(" <-> ");
else printf(" <-- ");
else
if (i==0) printf(" --> ");
else printf(" ");
printf("{%s}",newStates[i]);shift(dfaMaxLength,strlen(newStates[i]));printf(" |");
for (j = 0; j < nbrNewSymbols; j++)
printf(" {%s} ",DFA[i][j]);
printf("\n");
}
}
/******************************************************/
/******************************************************/
char*epClosure(char stat)
{ int i,j;char zz[max];
zz[0] = stat; zz[1]=0;
for (i=0;zz[i]!=0;i++) add_no_rpt(zz,nextStates(zz[i],epsilon));
return zz;
}
/******************************************************/
/******************************************************/
int findDfaState(char str[])
{
int i;
for(i=0;i<nbrNewStates;i++)
{
if (accepted(newStates[i],str)==true && strlen(str)==strlen(newStates[i])) return true;
}
return false;
}
/******************************************************/
/******************************************************/
int isFinalState(char state[])
{
int i;
for(i=0;state[i]!=0;i++) if (strchr(finalStates,state[i])!=NULL) return true;
return false;
}
/******************************************************/
/******************************************************/
char *makeDFAstate(char state[],int c)
{
int i,j;char kk[max],yy[max];
for (i=0;state[i]!=0;i++)
{
add_no_rpt(kk,nextStates(state[i],newSymbols[c]));
j=strlen(kk)-1;
add_no_rpt(kk,epClosure(kk[j]));
}
return kk;
}
have fun !

You have 2 functions epClosure and makeDFAstate that return addresses to local variables. This is undefined behavior and a likely cause to your problem.
To fix it either dynamically allocate memory (using malloc) for the variables or take an address to write to as an argument e.g. void epClosure(char stat, char* buf). You'd probably want to also pass the size of the buffer to make sure you don't write past it.

puts(mm) yields undefined behavior, because mm does not point to a string.

Related

How to return values over multiple functions, or declare a function implicit?

Im currently making a TicTacToe and Im passing 2 values through several functions. After the functions, I need the value to be returned to the main() function, or call the first function (here it is named 'eingabe'. Sadly, I dont know, how to pass 2 values over 4 functions or how to call a "yet undeclared" function.
Here you can see my Code:
#include <stdio.h>
#include <stdlib.h>
char spielfeld(char symbol[3][3], int counter){
printf("\n");
for(int i=0; i<4;i++){
for(int j =0; j<3;j++){
printf("+---");
}
printf("+\n");
if(i<3){
for(int k=0; k<3;k++){
if(symbol[i][k]== 0){
symbol[i][k]=" ";
}
printf("| %c ", symbol[i][k]);
}
printf("| ");
printf("%d\n",i);
}
}
printf(" A B C\n");
counter = counter +1;
eingabe(counter, symbol);
return(symbol, counter);
}
char symbolset(int auswahl[2], char* spieler, char symbol[3][3], int counter){
for(int i=0; i<3;i++){
for(int j=0; j<3;j++){
if(auswahl[0]==i && auswahl[1]==j){
symbol[i][j]= *spieler;
}
else{
symbol[i][j]=0;
}
}
}
spielfeld(symbol, counter);
return(symbol, counter);
}
char umwandlung(char* eingabe, char* spieler, char symbol[3][3], int counter){
int auswahl[2];
char* chara="aa";
char* charb="bb";
if(eingabe[1]==48){
auswahl[0]=0;
}
else if (eingabe[1]==49)
{
auswahl[0]=1;
}
else{
auswahl[0]=2;
}
if(eingabe[0]==chara[0]){
auswahl[1]=0;
}
else if (eingabe[0]==charb[0])
{
auswahl[1]=1;
}
else{
auswahl[1]=2;
}
symbolset(auswahl, spieler, symbol, counter);
return(symbol, counter);
}
char eingabe(int counter, char symbol[3][3]){
char* spieler = "X";
if(counter%2==0){
spieler = "X";
}
else{
spieler = "O";
}
int auswahl[2];
char* eingabe= calloc(2, sizeof(char));
scanf("%s", eingabe);
printf("%d", eingabe[1]);
umwandlung(eingabe, spieler, symbol, counter);
return(symbol, counter);
}
int main(){
int counter = 0;
char symbol[3][3];
printf("%d,%c",eingabe(counter, symbol));
eingabe(counter, symbol);
printf("%d,%c",eingabe(counter, symbol));
}
I tried already using a struct, but I still would need to pass it through all the functions, right? Any advices are welcome :) Thanks already
Return a struct
Close to OP's request.
typedef struct {
char symbol[3][3];
int counter;
} ttt;
ttt spielfeld(char symbol[3][3], int counter) {
ttt t;
...
return t;
}
// or
ttt spielfeld(ttt state) {
// or
ttt spielfeld(ttt *state) {
Pass in the location to save the new state as a struct *.
This is more C idiomatic.
// Perhaps return an error flag should something go wrong
bool spielfeld(ttt *new_state, char symbol[3][3], int counter) {
// or
bool spielfeld(ttt *new_state, ttt *old_state) {

Why is NULL printed here? - C-90

The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 500
#define M 100
/*Version 1*/
void replace_word(char *word);
void add_new_word_dictionary(void);
void do_nothing(void);
void return_basic(void);
void check_word(void);
void compute_words(void);
void compute_characters(void);
void compute_ch_sp(void);
void compute_num_dif_words(void);
void create_istogram(void);
void save_file(void);
int get_choice(void);
void return_word(void);
void insert_text(int numwords, char matrix[N][M], int posit);
int main() {
int j;
int choice = 0;
char matrix[N][M];
char word[40] = { "t" };
while (1) {
choice = get_choice();
if (choice == 0) {
insert_text(M, matrix, 1);
}
if (choice == 1) {
add_new_word_dictionary();
}
if (choice == 2) {
do_nothing();
}
if (choice == 3) {
save_file();
}
if (choice == 4) {
compute_words();
}
if (choice == 5) {
break;
}
for (j = 0; j < M; j++) {
printf("%s", matrix[N][M]);
}
}
printf("\n End of Program \n");
return 0;
}
void replace_word(char *word) {
return;
}
void add_new_word_dictionary(void) {
char word[50] = { "s" };
printf("\nPlease enter the word\n");
scanf("\n%s", word);
printf("Your word is %s", word);
return;
}
void do_nothing(void) {
printf("\n do_nothing \n");
return;
}
void return_basic(void) {
printf("\n return basic \n");
return;
}
void check_word(void) {
printf("\n check word \n");
return;
}
void compute_words(void) {
printf("\n compute_words \n");
return;
}
void compute_characters(void) {
printf("\n compute characters \n");
}
void compute_ch_sp(void) {
printf("\n compute_ch_sp \n");
return;
}
void compute_num_dif_words(void) {
printf("\n compute_num_same_words \n");
return;
}
void create_istogram(void) {
printf("\n create istogram \n");
return;
}
void save_file(void) {
printf("\n save_file \n");
return;
}
int get_choice(void) {
int choice = 0;
printf("\n Select a choice from the below \n");
printf("\n Select 0 to add text \n");
printf("\n Select 1 to add new words in the dictionary \n");
printf("\n Select 2 to enter enter correction mode \n");
printf("\n Select 3 to save the text \n");
printf("\n Select 4 to see the statistics about your text \n");
printf("\n Select 5 to exit the program\n");
scanf("\n%d", &choice);
return choice;
}
void insert_text(int numwords, char matrix[N][M], int posit) {
int i;
int j;
char word2[40] = { "" };
while (strcmp(word2, "*T*E*L*O*S*")) {
printf("\n Add the word \n");
scanf("\n%s", word2);
if (posit + 1 > numwords) {
printf("\n Out of Bounds \n ");
}
for (i = numwords - 2; i >= posit; i--) {
strcpy(matrix[i + 1], matrix[i]);
if (!i)
break;
}
strcpy(matrix[posit], word2);
j++;
}
for (i = 0; i < j; i++) {
printf("%s", matrix[i]);
printf("\n j is %d\n", j);
}
return;
}
The problem: I have a function called insert_text. This function adds a string in the 1st position of an array (at least that is what I think it does) and it is called if choice is 0 and executes itself until the string *Ī¤ELOS* is given. When in insert_text I print matrix I get a bunch of *(null)*s... I can count how many words matrix has (by declaring a variable j and incrementing by 1 inside the while loop, but that does not seem to work either. How can I fix this?
The printing code is incorrect: matrix is an array of N arrays of M characters, where you store null terminated C strings. As coded, you pass a single character just beyond the end of the array to printf for %s, which expects a string. The loop should be:
for (j = 0; j < N; j++) {
printf("%s ", matrix[j]);
}
Note that char matrix[N][M]; is uninitialized, so its contents will seem random. Initialize matrix as char matrix[N][M] = { "" };
Also note that in add_new_word_dictionary(), the scanf() conversion should be scanf("%49s", word); to prevent a potential buffer overflow if the user enters a very long word.
Same in insert_text, the code should be scanf("%39s", word2) ans you should test the return value to check for input errors.
Finally, arrays are indexed from 0 in C, so insert_text should be given a position of 0 and the number of words should be N, not M.
Both the test and the insertion loop have problems too.
Here is a modified version:
// call from main as insert_text(N, matrix, 0);
//
void insert_text(int numwords, char matrix[N][M], int posit) {
char word2[40];
int i, j = 0;
for (;;) {
printf("\n Add the word \n");
if (scanf("%39s", word2) != 1) {
break; // end of file or input error
}
if (!strcmp(word2, "TELOS")) {
break; // magic word
}
if (posit >= numwords) {
printf("\n Out of Bounds \n");
break;
}
for (i = numwords - 2; i >= posit; i--) {
strcpy(matrix[i + 1], matrix[i]);
}
strcpy(matrix[posit], word2);
j++;
}
for (i = 0; i < j; i++) {
printf("%s ", matrix[i]);
}
printf("\n j is %d\n", j);
}
Here is a modified version of the whole program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 500
#define M 100
/*Version 1*/
void replace_word(char *word);
void add_new_word_dictionary(void);
void do_nothing(void);
void return_basic(void);
void check_word(void);
void compute_words(void);
void compute_characters(void);
void compute_ch_sp(void);
void compute_num_dif_words(void);
void create_istogram(void);
void save_file(void);
int get_choice(void);
void return_word(void);
void insert_text(int numwords, char matrix[N][M], int posit);
int main() {
int j, done = 0;
char matrix[N][M] = { "" };
while (!done) {
switch (get_choice()) {
case 0:
insert_text(N, matrix, 0);
break;
case 1:
add_new_word_dictionary();
break;
case 2:
do_nothing();
break;
case 3:
save_file();
break;
case 4:
compute_words();
break;
default:
done = 1;
break;
}
for (j = 0; j < N; j++) {
if (matrix[j][0])
printf("%s ", matrix[j]);
}
printf("\n");
}
printf("\n End of Program \n");
return 0;
}
void add_new_word_dictionary(void) {
char word[50];
printf("\nPlease enter the word\n");
if (scanf("%49s", word) == 1)
printf("Your word is %s\n", word);
}
void replace_word(char *word) { printf("\n replace word \n"); }
void do_nothing(void) { printf("\n do_nothing \n"); }
void return_basic(void) { printf("\n return basic \n"); }
void check_word(void) { printf("\n check word \n"); }
void compute_words(void) { printf("\n compute_words \n"); }
void compute_characters(void) { printf("\n compute characters \n"); }
void compute_ch_sp(void) { printf("\n compute_ch_sp \n"); }
void compute_num_dif_words(void) { printf("\n compute_num_same_words \n"); }
void create_istogram(void) { printf("\n create istogram \n"); }
void save_file(void) { printf("\n save_file \n"); }
int get_choice(void) {
int choice = -1;
printf("\nSelect a choice from the below \n");
printf("Select 0 to add text \n");
printf("Select 1 to add new words in the dictionary \n");
printf("Select 2 to enter enter correction mode \n");
printf("Select 3 to save the text \n");
printf("Select 4 to see the statistics about your text \n");
printf("Select 5 to exit the program\n");
scanf("%d", &choice);
return choice;
}
// call from main as insert_text(N, matrix, 0);
//
void insert_text(int numwords, char matrix[N][M], int posit) {
char word2[40];
int i;
for (;;) {
printf("\n Add the word \n");
if (scanf("%39s", word2) != 1) {
break; // end of file or input error
}
if (!strcmp(word2, "TELOS")) {
break; // magic word
}
if (posit >= numwords) {
printf("\n Out of Bounds \n");
break;
}
for (i = numwords - 2; i >= posit; i--) {
strcpy(matrix[i + 1], matrix[i]);
}
strcpy(matrix[posit], word2);
posit++;
}
for (i = 0; i < posit; i++) {
printf("%s ", matrix[i]);
}
printf("\n posit is %d\n", posit);
}

How can I delete a user inputed element/data from an Array in Structure? [duplicate]

How to delete an element from the array of type structure? Let's say if I register an item and then want to delete it how can I do that? The delete function is at the end of the code. I want to delete the item by giving the varunummer (id number). Any one know how to do it?
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define WORDLENGTH 30
#define MAX 5
struct varor {
int varunummer;
char namn[WORDLENGTH];
int lagersaldo;
};
int readLine(char s[], int length);
int ifVarunummerExist(int varunummer, const struct varor reg[], int nrOfGoods);
void registerVaror(struct varor reg[], int *nrOfGoods);
void getPrint(const struct varor reg[], int nrOfGoods);
void avregristreraVaror(struct varor reg[], int nrOfGoods);
int main(void) {
struct varor vRegister[WORDLENGTH];
int nrOfGoods = 0;
int run = 1;
while (run) {
char choice;
printf("\n\t\tMeny - Lager Program\n\n\
(1) Register\n\b\b\b\b\
(2) Print\n\
(3) Delete\n\
(4) Quit\n");
scanf(" %c%*c", &choice);
if (choice=='1')
registerVaror(vRegister, &nrOfGoods);
if (choice=='2')
getPrint(vRegister, nrOfGoods);
if (choice=='3')
avregristreraVaror(vRegister, nrOfGoods);
else if (choice=='4')
run = 0;
}
return 0;
}
int ifVarunummerExist(int varunummer, const struct varor reg[], int nrOfGoods) {
int i;
for (i = 0; i < nrOfGoods; i++)
if(reg[i].varunummer == varunummer)
return i;
return -1;
}
int readLine(char s[], int length) {
int ch, i=0;
while (isspace(ch=getchar()));
while (ch != '\n' && ch != EOF) {
if (i < length)
s[i++] = ch;
ch = getchar();
}
s[i] = '\0';
return i;
}
void registerVaror(struct varor reg[], int *nrOfGoods) {
char namn[WORDLENGTH], tmp[WORDLENGTH];
int varunummer, lagersaldo;
if (*nrOfGoods == MAX) {
printf("\nError! Finns inte plats kvar!\n");
return;
}
printf("Ange varunummer: ");
scanf("%d", &varunummer);
if (ifVarunummerExist(varunummer, reg, *nrOfGoods) >= 0) {
printf("\nVarunummer finns redan!\n");
return;
}
reg[*nrOfGoods].varunummer = varunummer;
printf("Ange namn: ");
readLine(reg[*nrOfGoods].namn, WORDLENGTH);
printf("Ange lagersaldo :");
scanf("%d", &reg[*nrOfGoods].lagersaldo);
//reg[*nrOfGoods]=createVara(varunummer,namn,lagersaldo);
(*nrOfGoods)++;
}
void getPrint(const struct varor reg[], int nrOfGoods) {
int i;
printf("\nVarunummer \t Namn \t\t\t Lagersaldo\n");
for (i = 0; i < nrOfGoods; i++) {
printf(" %d \t\t %s \t\t\t %d\n",reg[i].varunummer,reg[i].namn,reg[i].lagersaldo);
}
}
void avregristreraVaror(struct varor reg[], int nrOfGoods) {
int run = 1;
while (run) {
char choice;
printf("\n (1) Delete \n (2) Exit");
scanf(" %c", &choice);
//DELETE IF CHOICE 1---------
if (choice == '1') {
int i, varunummer;
printf("Ange varunummer: ");
scanf("%d", &varunummer);
for (i = varunummer + 1; i < MAX; i++) {
reg[i - 1] = reg[i];
}
reg[i] = 0;
}
}
//QUIT TO MY MENU CHOICE 2--------
if (choice == '2')
run = 0;
}
You can try iterating through the array in a for loop UNTIL your varunummer is matched with the struct's property. Something along these lines (let's say you are searching for the member with varunummer = varunummerToLookFor), this shift all the elements in the array from the point onwards of your deletion by 1, hence, producing an array with the same sequence as before but with your wanted element removed. Hope that helps!
for(int i = 0, i < varorArraySize, i++){
if(varunummerToLookFor == varorArray[i].varunummer){
for (i = pos; i < varorArraySize - 1; i++)
{
varorArray[i] = varorArray[i + 1];
}
}
}

Parenthesis balance program crashing(c)

Good afternoon, i am trying to do a program that checks whether if a expression has its parentheses balanced or not but because of some problem that i can't quite find out the program is crashing, could somebody help me find a way so that the program works?
In
a * b - (2 + c)
Out
Correct
or
In
)3+b * (2-c)(
Out
Incorrect
The program should check only for parantheses and i am supposed to implement linear lists on the code.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SUCESSO 1 //Succes
#define FALHA -1 //Failure
#define CELULA_INVALIDA 0 //Invalid key
#define TAMANHO_MAXIMO 1000 //Max size
typedef struct{
char exp[1000];
unsigned int chave; //key
}celula; //node
typedef struct{
celula celulas[TAMANHO_MAXIMO]; //vector of nodes
unsigned int tamanho; //size of the list
}fila; //list
int criarFilaVazia(fila * ent){ //create an empty list
ent->tamanho = 0;
return(SUCESSO);
}
int insFinal(fila * ent, celula node){ //put a node on the end of the list
unsigned int i;
celula aux;
if(ent->tamanho == TAMANHO_MAXIMO){
return(FALHA);
}
else{
ent->celulas[ent->tamanho] = node;
ent->tamanho++;
return(SUCESSO);
}
}
void mostrarCelula(celula ent){ //show node
printf("%s \n", ent.exp);
}
void mostrarFila(fila ent){ //show entire list
unsigned int i;
if(ent.tamanho == 0){
printf("Fila vazia");
}
else{
printf("A fila possui %u element \n", ent.tamanho);
for(i=0; (i < ent.tamanho); i++){
printf("Elemento %u \n \n", (i+1));
mostrarCelula(ent.celulas[i]);
}
}
}
int main(){
int i, j;
fila exp;
celula aux;
scanf("%s", &aux.exp);
getchar();
aux.chave = 0;
insFinal(&exp, aux);
for(i = 0; i < strlen(exp.celulas[0].exp); i++){//checks all the array
if(exp.celulas[0].exp[i] == '('){//if there is an opening
for(j = i; j < strlen(exp.celulas[0].exp); j++){
if(exp.celulas[0].exp[j] == ')'){//should be and ending
exp.celulas[0].exp[i] = 0;//removes if balanced
exp.celulas[0].exp[j] = 0;
}
}
}
}
//checks for remaining parentheses and prints the output
for(i = 0; i < strlen(exp.celulas[0].exp); i++){
if(exp.celulas[0].exp[i] == '(' || exp.celulas[0].exp[i] == ')'){
printf("Incorreta"); //incorrect
}
else{
printf("Correta"); //correct
}
}
return 0;
}
[enter image description here][1]
Error message: https://i.stack.imgur.com/aeSn5.png
it says ex06 stopped working
Your program is crashing inside insFinal because the ent parameter passed in from main has uninitialized data. Hence, undefined behavior. Ammend these two lines at the beginning of main:
fila exp;
celula aux;
With this:
fila exp = {0};
celula aux = {0};
That will zero-init both.
The thing I don't get is what all these data structures are used for. Nor do I understand the double-nested for loop for checking the balance. Checking for a balanced set of parentheses in an expression should be as simple as this:
int areParenthesesBalanced(const char* str)
{
int balance = 0;
int len = str ? strlen(str) : 0;
for (int i = 0; i < len; i++)
{
if (str[i] == '(')
{
balance++;
}
else if (str[i] == ')')
{
balance--;
if (balance < 0)
{
return 0;
}
}
}
return (balance == 0) ? 1 : 0;
}
int main() {
char str[1000];
scanf("%s", str);
if (areParenthesesBalanced(str))
{
printf("Incorreta\n");
}
else
{
printf("Correta\n");
}
return 0;
}

scanf not passing value to variable

I wanted to ask a little bit about scanf in C using Xcode IDE. If I not initially set value for variable choice, anytime I open my program and enter any choice(either 1/2) it will go to else case every time. So I check the value after select any choice then I got a strange number. Could you please take a look at my code. Thank you in advance.
Here's my actual code:
/* Bubble Sort using MPI */
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>
#define N 1000
double startT,stopT;
double startTime;
void showElapsed(int id, char *m)
{
printf("%d: %s %f secs\n",id,m,(clock()-startTime)/CLOCKS_PER_SEC);
}
void showVector(int *v, int n, int id)
{
int i;
printf("%d: ",id);
for(i=0;i<n;i++)
printf("%d ",v[i]);
putchar('\n');
}
int * merge(int *v1, int n1, int *v2, int n2)
{
int i,j,k;
int * result;
result = (int *)malloc((n1+n2)*sizeof(int));
/*
i : pointer of v1
j : pointer of v2
k : pointer of k
*/
i=0; j=0; k=0;
while(i<n1 && j<n2)
if(v1[i]<v2[j])
{
result[k] = v1[i];
i++; k++;
}
else
{
result[k] = v2[j];
j++; k++;
}
if(i==n1)
while(j<n2)
{
result[k] = v2[j];
j++; k++;
}
else
while(i<n1)
{
result[k] = v1[i];
i++; k++;
}
return result;
}
void swap(int *v, int i, int j)
{
int t;
t = v[i];
v[i] = v[j];
v[j] = t;
}
void sort(int *v, int n)
{
int i,j;
for(i=n-2;i>=0;i--)
for(j=0;j<=i;j++)
if(v[j]>v[j+1])
swap(v,j,j+1);
}
int main(int argc, char **argv)
{
int * data;
int * chunk;
int * other;
int m,n=N;
int id,p;
int s;
int i;
int step;
int choice = 0;
//start asking user to select option between sequential or parallel version of BubbleSort
printf(":: Welcome to BubbleSort Project for CSS333 ::\n");
printf("Please select option that you prefer\n");
printf("Type \"1\" for sequential mode or \"2\" for parallel mode\n");
printf("");
fflush(stdout);
scanf("Enter here: %d", &choice);
printf("Test value of choice(should be either 1 or 2): %d\n", choice);
//end asking
if(choice == 1){
// do seq
printf("You have selected option 1 which is running BubbleSort in Sequential mode\n");
printf("Please wait...");
}
else if(choice == 2){
// do parallel
printf("You have selected option 2 which is running BubbleSort in parallel mode\n");
printf("Please wait...");
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&p);
if(id==0)
{
int r;
srandom(clock());
s = n/p;
r = n%p;
data = (int *)malloc((n+p-r)*sizeof(int));
for(i=0;i<n;i++)
data[i] = random();
if(r!=0)
{
for(i=n;i<n+p-r;i++)
data[i]=0;
s=s+1;
}
startT = clock();
MPI_Bcast(&s,1,MPI_INT,0,MPI_COMM_WORLD);
chunk = (int *)malloc(s*sizeof(int));
MPI_Scatter(data,s,MPI_INT,chunk,s,MPI_INT,0,MPI_COMM_WORLD);
sort(chunk,s);
}
else
{
MPI_Bcast(&s,1,MPI_INT,0,MPI_COMM_WORLD);
chunk = (int *)malloc(s*sizeof(int));
MPI_Scatter(&data,s,MPI_INT,chunk,s,MPI_INT,0,MPI_COMM_WORLD);
sort(chunk,s);
}
step = 1;
while(step<p)
{
if(id%(2*step)==0)
{
if(id+step<p)
{
MPI_Recv(&m,1,MPI_INT,id+step,0,MPI_COMM_WORLD,&status);
other = (int *)malloc(m*sizeof(int));
MPI_Recv(other,m,MPI_INT,id+step,0,MPI_COMM_WORLD,&status);
chunk = merge(chunk,s,other,m);
s = s+m;
}
}
else
{
int near = id-step;
MPI_Send(&s,1,MPI_INT,near,0,MPI_COMM_WORLD);
MPI_Send(chunk,s,MPI_INT,near,0,MPI_COMM_WORLD);
break;
}
step = step*2;
}
if(id==0)
{
FILE * fout;
stopT = clock();
printf("%d; %d processors; %f secs\n",N,p,(stopT-startT)/CLOCKS_PER_SEC);
fout = fopen("result","w");
for(i=0;i<s;i++)
if (chunk[i] != 0)
fprintf(fout,"%d\n",chunk[i]);
fclose(fout);
}
MPI_Finalize();
}
else{
printf("Invalid value\n");
printf("Program exiting...\n");
exit(0);
}
}
This is your problem:
scanf("Enter here: %d", &choice);
You might be expecting this to display "Enter here: " then accept a number as input and store it in the variable choice. But that's not what it does.
What this does is that it goes through the formatting string ("Enter here: %d"), one character by one. For each character that is not '%', it reads a character from stdin and compares them together. If they don't match, it pushes the character back to the buffer of stdin and stops scanning.
So unless the user types in something starting with Enter here: followed immediately by a number, it fails at reading that number.
What you probably wanted to do is to:
printf("Enter here: ");
scanf("%d", &choice);
(and then read the documentation for scanf().

Resources