*/
void do_cmd_colors(PlayerType *player_ptr)
{
- char tmp[160];
FILE *auto_dump_stream;
screen_save();
+ const auto initial_filename = format("%s.prf", player_ptr->base_name);
while (true) {
term_clear();
prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
case '1': {
prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
prt(_("ファイル: ", "File: "), 10, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 70)) {
+ const auto ask_result = askfor(70, initial_filename);
+ if (!ask_result) {
continue;
}
- (void)process_pref_file(player_ptr, tmp, true);
+ (void)process_pref_file(player_ptr, *ask_result, true);
term_xtra(TERM_XTRA_REACT, 0);
term_redraw();
break;
constexpr auto mark = "Colors";
prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
prt(_("ファイル: ", "File: "), 10, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 70)) {
+ const auto ask_result = askfor(70, initial_filename);
+ if (!ask_result) {
continue;
}
- const auto &path = path_build(ANGBAND_DIR_USER, tmp);
+ const auto &path = path_build(ANGBAND_DIR_USER, *ask_result);
if (!open_auto_dump(&auto_dump_stream, path, mark)) {
continue;
}
*/
void do_cmd_macros(PlayerType *player_ptr)
{
- char tmp[1024];
char buf[1024];
static char macro_buf[1024];
FILE *auto_dump_stream;
};
print_macro_menu();
+ const auto initial_filename = format("%s.prf", player_ptr->base_name);
while (true) {
msg_print(_("コマンド: ", "Command: "));
const auto key = inkey();
case '1': {
prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
prt(_("ファイル: ", "File: "), 18, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 80)) {
+ const auto ask_result = askfor(70, initial_filename);
+ if (!ask_result) {
continue;
}
- const auto err = process_pref_file(player_ptr, tmp, true);
+ const auto err = process_pref_file(player_ptr, *ask_result, true);
+ const auto *mes = ask_result->data();
if (-2 == err) {
- msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
+ msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), mes);
} else if (err) {
- msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
+ msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), mes);
} else {
- msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
+ msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), mes);
}
break;
case '2': {
prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
prt(_("ファイル: ", "File: "), 18, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 80)) {
+ const auto ask_result = askfor(70, initial_filename);
+ if (!ask_result) {
continue;
}
- macro_dump(&auto_dump_stream, tmp);
+ macro_dump(&auto_dump_stream, *ask_result);
msg_print(_("マクロを追加しました。", "Appended macros."));
break;
}
// マクロの作成時に参照するためmacro_bufにコピーする
strncpy(macro_buf, macro_actions[k].data(), sizeof(macro_buf) - 1);
- // too long macro must die
- strncpy(tmp, macro_buf, 80);
+ char tmp[81]{};
+ angband_strcpy(tmp, macro_buf, 80);
tmp[80] = '\0';
ascii_to_text(buf, tmp, sizeof(buf));
prt(buf, 22, 0);
prt(_("マクロ行動: ", "Action: "), 20, 0);
// 最後に参照したマクロデータを元に作成する(コピーを行えるように)
macro_buf[80] = '\0';
+ char tmp[81]{};
ascii_to_text(tmp, macro_buf, sizeof(tmp));
- if (!askfor(tmp, 80)) {
+ const auto ask_result = askfor(80, tmp);
+ if (!ask_result) {
break;
}
- text_to_ascii(macro_buf, tmp, sizeof(macro_buf));
+ text_to_ascii(macro_buf, *ask_result, sizeof(macro_buf));
macro_add(buf, macro_buf);
msg_print(_("マクロを追加しました。", "Added a macro."));
break;
case '6': {
prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
prt(_("ファイル: ", "File: "), 18, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 80)) {
+ const auto ask_result = askfor(80, initial_filename);
+ if (!ask_result) {
continue;
}
- (void)keymap_dump(tmp);
+ (void)keymap_dump(*ask_result);
msg_print(_("キー配置を追加しました。", "Appended keymaps."));
break;
}
// マクロの作成時に参照するためmacro_bufにコピーする
strncpy(macro_buf, act, sizeof(macro_buf) - 1);
// too long macro must die
+ char tmp[81]{};
strncpy(tmp, macro_buf, 80);
tmp[80] = '\0';
ascii_to_text(buf, tmp, sizeof(buf));
prt(_("行動: ", "Action: "), 20, 0);
// 最後に参照したマクロデータを元に作成する(コピーを行えるように)
macro_buf[80] = '\0';
+ char tmp[81]{};
ascii_to_text(tmp, macro_buf, sizeof(tmp));
- if (!askfor(tmp, 80)) {
+ const auto ask_result = askfor(80, tmp);
+ if (!ask_result) {
break;
}
- text_to_ascii(macro_buf, tmp, sizeof(macro_buf));
+ text_to_ascii(macro_buf, *ask_result, sizeof(macro_buf));
string_free(keymap_act[mode][(byte)(buf[0])]);
keymap_act[mode][(byte)(buf[0])] = string_make(macro_buf);
msg_print(_("キー配置を追加しました。", "Added a keymap."));
"Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."),
22, 0);
prt(_("マクロ行動: ", "Action: "), 20, 0);
- buf[0] = '\0';
- if (!askfor(buf, 80)) {
+ const auto ask_result = askfor(80);
+ if (!ask_result) {
continue;
}
- text_to_ascii(macro_buf, buf, sizeof(macro_buf));
+ text_to_ascii(macro_buf, *ask_result, sizeof(macro_buf));
break;
}
default:
switch (skey) {
case '=': {
prt(_("強調: ", "Show: "), hgt - 1, 0);
- char ask[81]{};
- angband_strcpy(ask, shower_str, 80);
- const auto back_str(shower_str);
- if (askfor(ask, 80)) {
- shower = ask;
- shower_str = ask;
- } else {
- shower_str = back_str;
+ const auto ask_result = askfor(80, shower_str);
+ if (ask_result) {
+ shower = *ask_result;
+ shower_str = *ask_result;
}
continue;
case '/':
case KTRL('s'): {
prt(_("検索: ", "Find: "), hgt - 1, 0);
- char ask[81]{};
- angband_strcpy(ask, finder_str, 80);
- const auto back_str(finder_str);
- if (!askfor(ask, 80)) {
- finder_str = back_str;
+ const auto ask_result = askfor(80, finder_str);
+ if (!ask_result) {
continue;
}
- finder_str = ask;
+ finder_str = *ask_result;
if (finder_str.empty()) {
shower = "";
continue;
void do_cmd_visuals(PlayerType *player_ptr)
{
FILE *auto_dump_stream;
- char tmp[160];
bool need_redraw = false;
concptr empty_symbol = "<< ? >>";
if (use_bigtile) {
}
screen_save();
+ const auto initial_filename = format("%s.prf", player_ptr->base_name);
while (true) {
term_clear();
print_visuals_menu(nullptr);
case '0': {
prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
prt(_("ファイル: ", "File: "), 17, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 70)) {
+ const auto ask_result = askfor(70, initial_filename);
+ if (!ask_result) {
continue;
}
- (void)process_pref_file(player_ptr, tmp, true);
+ (void)process_pref_file(player_ptr, *ask_result, true);
need_redraw = true;
break;
}
case '1': {
prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
prt(_("ファイル: ", "File: "), 17, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 70)) {
+ const auto ask_result = askfor(70, initial_filename);
+ if (!ask_result) {
continue;
}
- const auto &path = path_build(ANGBAND_DIR_USER, tmp);
+ const auto &path = path_build(ANGBAND_DIR_USER, *ask_result);
constexpr auto mark = "Monster attr/chars";
if (!open_auto_dump(&auto_dump_stream, path, mark)) {
continue;
case '2': {
prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
prt(_("ファイル: ", "File: "), 17, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 70)) {
+ const auto ask_result = askfor(70, initial_filename);
+ if (!ask_result) {
continue;
}
- const auto &path = path_build(ANGBAND_DIR_USER, tmp);
+ const auto &path = path_build(ANGBAND_DIR_USER, *ask_result);
constexpr auto mark = "Object attr/chars";
if (!open_auto_dump(&auto_dump_stream, path, mark)) {
continue;
case '3': {
prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
prt(_("ファイル: ", "File: "), 17, 0);
- strnfmt(tmp, sizeof(tmp), "%s.prf", player_ptr->base_name);
- if (!askfor(tmp, 70)) {
+ const auto ask_result = askfor(70, initial_filename);
+ if (!ask_result) {
continue;
}
- const auto &path = path_build(ANGBAND_DIR_USER, tmp);
+ const auto &path = path_build(ANGBAND_DIR_USER, *ask_result);
constexpr auto mark = "Feature attr/chars";
if (!open_auto_dump(&auto_dump_stream, path, mark)) {
continue;
#include <stdexcept>
#include <string>
+namespace {
+std::vector<char> clear_buffer(int len, std::string_view initial_value)
+{
+ std::vector<char> buf(len + 1, '\0');
+ initial_value.copy(buf.data(), len);
+ return buf;
+}
+}
+
/*
* Get some string input at the cursor location.
* Assume the buffer is initialized to a default string.
* ESCAPE clears the buffer and the window and returns FALSE.
* RETURN accepts the current buffer contents and returns TRUE.
*/
-bool askfor(char *buf, int len, bool numpad_cursor)
+std::optional<std::string> askfor(int len, std::string_view initial_value, bool numpad_cursor)
{
/*
* Text color
len = MAIN_TERM_MIN_COLS - x;
}
- buf[len] = '\0';
+ auto buf = clear_buffer(len, initial_value);
auto pos = 0;
while (true) {
term_erase(x, y, len);
- term_putstr(x, y, -1, color, buf);
+ term_putstr(x, y, -1, color, buf.data());
term_gotoxy(x + pos, y);
const auto skey = inkey_special(numpad_cursor);
switch (skey) {
case SKEY_BOTTOM:
case KTRL('e'):
color = TERM_WHITE;
- pos = std::string_view(buf).length();
+ pos = std::string_view(buf.data()).length();
break;
case ESCAPE:
- buf[0] = '\0';
- return false;
+ return std::nullopt;
case '\n':
case '\r':
- return true;
+ return buf.data();
case '\010': {
auto i = 0;
color = TERM_WHITE;
break;
}
default: {
- char tmp[100];
if (skey & SKEY_MASK) {
break;
}
const auto c = static_cast<char>(skey);
if (color == TERM_YELLOW) {
- buf[0] = '\0';
+ buf = clear_buffer(len, "");
color = TERM_WHITE;
}
- strcpy(tmp, buf + pos);
+ const auto str_right_cursor = std::string(buf.data()).substr(pos);
#ifdef JP
if (iskanji(c)) {
inkey_base = true;
}
buf[pos] = '\0';
- angband_strcat(buf, tmp, len + 1);
+ angband_strcat(buf.data(), str_right_cursor, buf.size());
break;
}
}
{
msg_print(nullptr);
prt(prompt, 0, 0);
- char buf[1024]{};
- angband_strcpy(buf, initial_value, sizeof(buf));
- const auto res = askfor(buf, len, numpad_cursor);
+ const auto ask_result = askfor(len, initial_value, numpad_cursor);
prt("", 0, 0);
- if (!res) {
- return std::nullopt;
- }
-
- return buf;
+ return ask_result;
}
/*
};
class PlayerType;
-bool askfor(char *buf, int len, bool numpad_cursor = true);
+std::optional<std::string> askfor(int len, std::string_view initial_value = "", bool numpad_cursor = true);
std::optional<std::string> input_string(std::string_view prompt, int len, std::string_view initial_value = "", bool numpad_cursor = true);
bool input_check(std::string_view prompt);
bool input_check_strict(PlayerType *player_ptr, std::string_view prompt, UserCheck one_mode);
int wid, hgt;
term_get_size(&wid, &hgt);
- char finder_str[81] = "";
- char shower_str[81] = "";
char hook[68][32]{};
auto stripped_names = str_split(name_with_tag, '#');
auto &name = stripped_names[0];
term_clear();
std::string find;
+ std::string finder_str;
std::string shower;
+ std::string shower_str;
while (true) {
if (line >= size - rows) {
line = size - rows;
break;
case '=': {
prt(_("強調: ", "Show: "), hgt - 1, 0);
- char back_str[81];
- strcpy(back_str, shower_str);
- if (!askfor(shower_str, 80)) {
- strcpy(shower_str, back_str);
+ auto ask_result = askfor(80, shower_str);
+ if (!ask_result) {
break;
}
- if (!shower_str[0]) {
+ shower_str = *ask_result;
+ if (shower_str.empty()) {
shower.clear();
break;
}
- str_tolower(shower_str);
+ str_tolower(shower_str.data());
shower = shower_str;
break;
}
case '/':
case KTRL('s'): {
prt(_("検索: ", "Find: "), hgt - 1, 0);
- char back_str[81];
- strcpy(back_str, finder_str);
- if (!askfor(finder_str, 80)) {
- strcpy(finder_str, back_str);
+ auto ask_result = askfor(80, finder_str);
+ if (!ask_result) {
break;
}
- if (!finder_str[0]) {
+ finder_str = *ask_result;
+ if (finder_str.empty()) {
shower.clear();
break;
}
find = finder_str;
back = line;
line = line + 1;
- str_tolower(finder_str);
+ str_tolower(finder_str.data());
shower = finder_str;
break;
}
case '#': {
- char tmp[81];
prt(_("行: ", "Goto Line: "), hgt - 1, 0);
constexpr auto initial_goto = "0";
while (true) {
- strcpy(tmp, initial_goto);
- if (!askfor(tmp, 10)) {
+ const auto ask_result = askfor(10, initial_goto);
+ if (!ask_result) {
break;
}
try {
- line = std::stoi(tmp);
+ line = std::stoi(*ask_result);
break;
} catch (std::invalid_argument const &) {
prt(_("数値を入力して下さい。", "Please input numeric value."), hgt - 1, 0);
- continue;
} catch (std::out_of_range const &) {
prt(_("入力可能な数値の範囲を超えています。", "Input value overflows the maximum number."), hgt - 1, 0);
- continue;
}
}
break;
case '%': {
prt(_("ファイル・ネーム: ", "Goto File: "), hgt - 1, 0);
- char tmp[81];
- strcpy(tmp, _("jhelp.hlp", "help.hlp"));
- if (!askfor(tmp, 80)) {
+ const auto ask_result = askfor(80, _("jhelp.hlp", "help.hlp"));
+ if (!ask_result) {
break;
}
- if (!show_file(player_ptr, true, tmp, 0, mode)) {
+ if (!show_file(player_ptr, true, *ask_result, 0, mode)) {
skey = 'q';
}
prt(_("キャラクターの記録をファイルに書き出すことができます。", "You may now dump a character record to one or more files."), 21, 0);
prt(_("リターンキーでキャラクターを見ます。ESCで中断します。", "Then, hit RETURN to see the character, or ESC to abort."), 22, 0);
while (true) {
- char out_val[160] = "";
put_str(_("ファイルネーム: ", "Filename: "), 23, 0);
- if (!askfor(out_val, 60)) {
+ const auto ask_result = askfor(60);
+ if (!ask_result || ask_result->empty()) {
return;
}
- if (!out_val[0]) {
- break;
- }
screen_save();
- file_character(player_ptr, out_val);
+ file_character(player_ptr, *ask_result);
screen_load();
}
}