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

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

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

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1327閲覧

C++:スタックオーバーフローについて

aluminium

総合スコア7

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/09/25 05:14

初心者の学生です。どうぞ宜しくお願いいたします。
学校コードから内線番号を表示するプログラムの課題を解いています。

送信プログラムで「readSchoolcode関数でスタックオーバーフローが起きている」と警告され、課題の送信ができません。ポインタ「code」で起きているようなのですが、どのように解決したらいいでしょうか。また、どのくらいメモリを使っているか調べる方法はあるのでしょうか。

お知恵をお借りできれば幸いです。お時間ありがとうございます。

ご参考

イメージ説明

C++

1#define _CRT_SECURE_NO_WARNINGS 2#include <iostream> 3#include <cstring> 4#include <cstdio> 5using namespace std; 6 7struct Extension { 8 char m_codes[5]; // 学校コード 9 int m_extnum; // 内線番号 10}; 11 12FILE* fptr; 13Extension nums[24]; 14 15bool loadExtensions(); 16bool hasCode(const Extension* mvp, const char code[]); 17void displayExtension(const Extension* mvp); 18void displayExtensionsWithCode(const char code[]); 19 20bool openFile(const char filename[]); 21void closeFile(); 22 23bool readSchoolcode(char codes[]); 24bool readExtension(int* extnum); 25 26void flushkeys(); 27bool yes(); 28 29int main() { 30 bool done = false; 31 char code[5]; 32 loadExtensions(); 33 cout << "内線番号検索" << endl << endl; 34 while (!done) { 35 cout << "学校コードを入力してください: "; 36 cin >> code; 37 flushkeys(); 38 displayExtensionsWithCode(code); 39 cout << "他の検索をしますか? (Y)es: "; 40 done = !yes(); 41 cout << endl; 42 } 43 cout << "検索を終了します" << endl; 44 return 0; 45} 46 47// バッファクリア 48void flushkeys() { 49 while (cin.get() != '\n'); 50} 51 52// y or Y が入力されたらtrue 53bool yes() { 54 char ch = cin.get(); 55 flushkeys(); 56 return ch == 'y' || ch == 'Y'; 57} 58 59// 内線番号読み込み 60bool loadExtensions() { 61 Extension mv; 62 int mnum = 0; // number of data read 63 bool ok = true; 64 if (openFile("schools.dat")) { 65 while (ok && mnum < 24) { 66 ok = readSchoolcode(mv.m_codes) && readExtension(&mv.m_extnum); 67 if (ok) nums[mnum++] = mv; 68 } 69 closeFile(); 70 } 71 return mnum == 24; 72} 73 74// 内線番号を探す 75bool hasCode(const Extension* mvp, const char code[]) { 76 int i = 0; 77 bool found = false; 78 while (!found && mvp->m_codes[i]) { 79 if (strstr(&mvp->m_codes[i++], code)) { //find code from school.dat 80 found = true; 81 } 82 } 83 return found; 84} 85 86// 内線番号を表示する 87void displayExtension(const Extension* mvp) { 88 cout << "333 444 5050 x " << mvp->m_extnum << endl; 89} 90 91// 学校コードから内線番号を探す 92void displayExtensionsWithCode(const char code[]) { 93 int i, j; 94 for (i = 0, j = 1; i < 24; i++) { 95 if (hasCode(&nums[i], code)) { 96 j++; 97 displayExtension(&nums[i]); 98 } 99 } 100 if (j == 1) { 101 cout << code << " という学校コードは見つかりませんでした" << endl; 102 } 103} 104 105// ファイルを開く 106bool openFile(const char filename[]) { 107 fptr = fopen(filename, "r"); 108 return fptr != NULL; 109} 110 111// ファイルを閉じる 112void closeFile() { 113 if (fptr) fclose(fptr); 114} 115 116// 学校コードを読み込み、成功したらtrueを返す 117bool readSchoolcode(char code[]) { 118 char codes[6]; 119 int gi = 0; //codes index; 120 int i = 0;// code[i] index 121 bool res = fscanf(fptr, "%[^|]|", codes); 122 if (res) { //spreading csv to array of strings 123 res = false; 124 while (codes[gi]) { 125 code[i++] = codes[gi++]; 126 res = true; 127 } 128 } 129 code[i++] = '\0'; 130 code[i] = '\0'; // NULL terminating the array of strings 131 return res; 132} 133 134// 内線番号を読み込み、成功したらtrueを返す 135bool readExtension(int* extnum) { 136 return fscanf(fptr, "%d\n", extnum) == 1; 137}

データファイル(schools.dat)

AFS| 12345 HTM| 23456 IBM| 34567 LHR| 45678 LPOA| 54321 ELI| 45673 ASC| 98325 ELS| 39512 CAA| 40032 FSN| 81944 MKT| 29401 MDA| 24911 CSS| 33091 ECE| 91223 HSS| 19834 NRS| 99331 PSF| 98765 RES| 87654 SAV| 76543 BSAC| 65432 EMET| 54541 FPET| 34332 ITAS| 11245 SDDS| 24234

補足情報

このサイトでコンパイルしたときはエラーが出ませんでした
https://www.onlinegdb.com/online_c_compiler

課題の送信はLinuxサーバ上で行いましたが、チェックプログラムが何で出来ているのかはわかりません...(すみません)

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

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

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

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

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

guest

回答1

0

ベストアンサー

codesは[6]ですがcodeは[5]です

codes = "XXXX\0\0"だったとすると

C++

1 if (res) { //spreading csv to array of strings 2 res = false; 3 while (codes[gi]) { 4 code[i++] = codes[gi++]; 5 res = true; 6 } 7 } 8 code[i++] = '\0'; 9 code[i] = '\0'; // NULL terminating the array of strings

whileを抜けた時点でi=gi=4です。
なので続く処理で

C++

1 code[4] = '\0'; 2 code[5] = '\0'; // NULL terminating the array of strings

となり、codeの範囲0~4を超えます

投稿2020/09/25 06:06

ozwk

総合スコア13521

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

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

aluminium

2020/09/25 23:25

whileを抜けた時点の説明がとてもわかりやすかったです。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問