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

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

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

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

Q&A

1回答

515閲覧

c言語、逆ポーランド記法

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

1クリップ

投稿2024/05/14 06:26

実現したいこと

逆ポーランド記法を用いた計算結果を求めるコードを知りたいです。
スタックやスタックに関する関数を使っており、ファイル(テキスト)を開いて中の文字列を読み取って計算します。

発生している問題・分からないこと

デバッグした際にfopenでファイルを開いても文字列を読み取れないのか、関係ない数列が表示される。

該当のソースコード

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> typedef int STACK_ITEM; #define STACK_SIZE 30 STACK_ITEM stack[STACK_SIZE]; int sp = 0;//スタックポイント //Init スタックを初期化する void Init() { sp = 0; } //IsEmpty スタックが空かどうかを調べる int Isempty(void) { if (sp == 0) { return 1; } else { return 0; } } //Push 引数の値をスタックに積み上げる void Push(STACK_ITEM data) { if (sp < STACK_SIZE) { stack[sp] = data; sp++; } } //Pop スタックの先頭から要素を取り出す STACK_ITEM Pop(void) { if (sp > 0) { sp--; return stack[sp]; } else { return 0; } } /* 入力ファイルを読み込み、計算結果を出力する 入力ファイルには1行ポーランド記述法で数式が記入されている。 空白を区切り文字とする。 入力ファイルの記入例:3 5 * 10 2 * - 上の記入例は次式 3*5-10*2 を示している */ int main(void) { STACK_ITEM a, b; Init(); char s[100]; FILE *fp; char infile[30]; printf("Input File:"); scanf("%s", infile); fp = fopen(infile, "r"); while (fscanf(fp, "%s", s) != EOF) { if (s == '+') { b = Pop(sp); a = Pop(sp); a = a + b; Push(a); printf("%d\n", a); } else if (s == '-') { b = Pop(sp); a = Pop(sp); a = a - b; Push(a); printf("%d\n", a); } else if (s == '*') { b = Pop(sp); a = Pop(sp); a = a * b; Push(a); printf("%d\n", a); } else { atoi(s); Push(s); printf("%d\n", &s); } } printf("%d\n", Pop()); fclose(fp); return 0; }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

whileの中身をprintfにしてfscanfの中身を表示させるだけのコードに変えても結果は変わらなかった。

補足

特になし

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2024/05/14 06:39

そもそもコンパイルが通りません
hiroki-o

2024/05/14 13:38

確かに、gccとかだとコンパイルは通りませんが、Visual Studioですよね。 1行目に、#define _CRT_SECURE_NO_WARNINGSがあるので。 warningてんこ盛りだけど、一応コンパイルは通る。 ここからなのに、退会してしまって残念ですね。
otn

2024/05/14 14:07

> warningてんこ盛りだけど、一応コンパイルは通る。 VCはほぼ使ったこと無いのですが、引数の個数が違ってもエラーじゃなくて警告がでるのみで、動いちゃうんですか?
hiroki-o

2024/05/14 14:19

VC好きとしては、VC一般的な話だと思ってほしくないけど、このソースに限っては動きます。 まさに質問者さんの言う通り、 「デバッグした際にfopenでファイルを開いても文字列を読み取れないのか、関係ない数列が表示される。」 なのです。まさか、「コンパイルが通りません」で、はね返されるとは思っていなかったことでしょう。 残念です。
otn

2024/05/14 16:41

情報ありがとうございます。実引数が多くても、余分なのは無視して動くと言うことですか。足りない場合はさすがにエラーですよね? Cの規格的には、個数が異なれば未定義なので動いてもよいということか。 未定義動作で動いているプログラムのデバッグはちょっと意欲がそがれます。
jimbe

2024/05/15 17:28

良くも悪くも流石 MS 製という感じ。
guest

回答1

0

問題のあった main だけです。
※が修正行です。(VisualStudio ではコンパイルエラーにならないそうな所も修正しています。)

c

1int main(void) { 2 STACK_ITEM a, b; 3 Init(); 4 char s[100]; 5 FILE *fp; 6 char infile[30]; 7 8 printf("Input File:"); 9 scanf("%s", infile); 10 fp = fopen(infile, "r"); 11 12 while (fscanf(fp, "%s", s) != EOF) { 13 if (*s == '+') { //※ 14 b = Pop(); //※ 15 a = Pop(); //※ 16 a = a + b; 17 Push(a); 18 printf("%d\n", a); 19 } 20 else if (*s == '-') { //※ 21 b = Pop(); //※ 22 a = Pop(); //※ 23 a = a - b; 24 Push(a); 25 printf("%d\n", a); 26 } 27 else if (*s == '*') { //※ 28 b = Pop(); //※ 29 a = Pop(); //※ 30 a = a * b; 31 Push(a); 32 printf("%d\n", a); 33 } 34 else { 35 a = atoi(s); //※ 36 Push(a); //※ 37 printf("%d\n", a); //※ 38 } 39 } 40 printf("%d\n", Pop()); 41 fclose(fp); 42 return 0; 43}

paiza.io にて、ファイル名の入力・ファイルオープンを消して fp = stdin; とし "3 5 * 10 2 * -" を入力

3 5 15 10 2 20 -5 -5

投稿2024/05/15 18:12

jimbe

総合スコア13318

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

アカウントをお持ちの方は

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問