質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

解決済

中間記法から逆ポーランド/シグメントエラー

sakippe
sakippe

総合スコア21

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

2回答

0評価

0クリップ

410閲覧

投稿2022/06/08 04:52

編集2022/06/10 15:16

中間記法から逆ポーランドに変換するプログラムを作っていて、コンパイルはできたのですが、「セグメントエラー」と表示され困っています。例えば、read<1+5と実行すると次の行に「セグメントエラー」出てしまいます。どこがいけないのでしょうか。

C

#include <stdio.h> #include <string.h> #include <stdlib.h> #include "lib1.h" #define MAX_TOKEN_NUM 200 #define QUEUE_SIZE 100 typedef char *QUEUE_TYPE; #define STACK_SIZE 100 typedef char *STACK_TYPE; QUEUE_TYPE gQueue[QUEUE_SIZE]; int gQNum = 0; STACK_TYPE gStack[STACK_SIZE]; int gSNum = 0; void initQueue(void){ gQNum = 0; } void initStack(void){ gSNum = 0; } int isStackEmpty(void){ return gSNum == 0; } void push(STACK_TYPE x){ gStack[gSNum] = x; gSNum++; } STACK_TYPE pop(void){ STACK_TYPE x; x = gStack[gSNum - 1]; gSNum--; return x; } void enqueue(QUEUE_TYPE x){ gQueue[gQNum++] = x; } /*tを数字、演算子、"("、")"のどれかを判断する 参考work37のtaiou関数 数字を0(else)、演算子を1、"("を2、")"を3*/ int tnohantei(char *t){ int result; if(strcmp(t, "+") == 0){ result = 1; }else if(strcmp(t, "-") == 0){ result = 1; }else if(strcmp(t, "*") == 0){ result = 1; }else if(strcmp(t, "/") == 0){ result = 1; }else if(strcmp(t, "(") == 0){ result = 2; }else if(strcmp(t, ")") == 0){ result = 3; }else{ result = 0; } return result; } void enzansizyouken(char *ops, char *opt){ char *op1 = "+"; char *op2 = "-"; char *op3 = "*"; char *op4 = "/"; char *stacktop = gStack[gSNum-1]; char *x; if(strcmp(ops, op1) == 0 && strcmp(opt, op3) == 0){ push(opt); }else if(strcmp(ops, op1) == 0 && strcmp(opt, op4) == 0){ push(opt); }else if(strcmp(ops, op2) == 0 && strcmp(opt, op3) == 0){ push(opt); }else if(strcmp(ops, op2) == 0 && strcmp(opt, op4) == 0){ push(opt); }else{ while(!isStackEmpty() || strcmp(stacktop,"(") != 0 || strcmp(stacktop,op3) != 0 || strcmp(stacktop,op4) != 0){ x = pop(); enqueue(x); } push(opt); } return; } int main(int argc, char *argv[]){ char *token[MAX_TOKEN_NUM]; char *k; char *t; char *a; int tnum, i, suuzi; tnum = read(token, MAX_TOKEN_NUM); /* 最初の入力 */ while (tnum > 0){ initQueue(); initStack(); for(i=0;i<tnum;i++){ t = token[i]; suuzi = tnohantei(token[i]); if(suuzi == 0){ enqueue(t); }else if(suuzi == 1){ enzansizyouken(argv[1], argv[2]); }else if(suuzi == 2){ push(t); }else if(suuzi == 3){ while(!k){ k = pop(); enqueue(k); if(isStackEmpty()){ printf("スタックエラー"); } } } } while(!isStackEmpty()){ a = pop(); if(strcmp(a, "(") == 0){ printf("エラー\n"); }else{ enqueue(a); } } /*トークンの中を表示*/ for (i=0; i<tnum; i++){ printf("token[%d]:%-4s ", i, token[i]); tnum = read(token, MAX_TOKEN_NUM); /* 次の入力 */ } return 0; }

lib1は先生の補助プログラムを使っています。変更できません。
int read(char *token[], int n)
キーボードから数式を読み込み,数式の構成要素(トークン)に分割する.分割
した各トークンは文字列の形で,第 1 引数に指定した配列 token に格納される.

C

#define MAX_INPUT_STRLEN 512 /* 1回の入力の最大長 */ #define BUFCOUNT 64 /* 標準入力から1行分の文字列を読み込み,トークンに分割する. * 第1引数: token[]: 分割した各トークン(文字列)を格納する配列. * 第2引数: maxTokenNum: token[]の要素数. * 第3引数: 読み込んだトークンの個数. * 戻り値: 読み込んだトークンの個数. */ static int read_core(char *token[], int maxTokenNum){ static char buf[BUFCOUNT][MAX_INPUT_STRLEN * 2]; static int k=-1; static int callcnt = 0; int i, j; char str[MAX_INPUT_STRLEN]; int count; if (callcnt++ > 0){ printf("\n"); } printf("read> "); fflush(stdout); if (fgets(str, MAX_INPUT_STRLEN, stdin) == NULL){ token[0] = NULL; count = -1; return -1; } i = 0; j = 0; k = (k+1)%BUFCOUNT; count = 0; while (str[i] != '\0'){ if (isWhitespace(str[i])){ i++; continue; } else if (str[i]=='q' || str[i]=='Q'){ count = -1; return -1; } else if (isNumberChar(str[i]) || str[i]=='.'){ int dotcnt = 0; token[(count)++] = &buf[k][j]; while (isNumberChar(str[i]) || str[i] == '.'){ if (str[i] == '.'){ dotcnt++; } buf[k][j++] = str[i++]; } buf[k][j++] = '\0'; if (dotcnt >= 2){ fprintf(stderr, "Error: read(): 小数点が2個以上ある数値(%s)を読み込みました\n", buf[k]); exit(1); } if (buf[k][0]=='.' || buf[k][j-2]=='.' ){ fprintf(stderr, "Error: read(): 実数(%s)の形式が不正です.\n", buf[k]); exit(1); } } else if (isSymbolChar(str[i])){ token[(count)++] = &buf[k][j]; buf[k][j++] = str[i++]; buf[k][j++] = '\0'; } else { printf("Error: read(): 未知の文字('%c', %d)を検出しました\n", str[i], str[i]); exit(1); } if (count > maxTokenNum-1){ fprintf(stderr, "Error: read(): 分割したトークンの数が多過ぎます.\n"); exit(1); } } return count; } int read(char *token[], int maxTokenNum){ int r; r = read_core(token, maxTokenNum); while (r == 0){ r = read_core(token, maxTokenNum); } return r; }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

can110

2022/06/08 05:02

read関数の実装(ソース)も提示ください。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。