OSDN Git Service

[Refactor] #2651 get_random_line() の引数からchar *を削除し、返り値をstd::optional<std::string...
authorHourier <66951241+Hourier@users.noreply.github.com>
Sun, 25 Dec 2022 03:01:56 +0000 (12:01 +0900)
committerHourier <66951241+Hourier@users.noreply.github.com>
Tue, 27 Dec 2022 08:39:03 +0000 (17:39 +0900)
12 files changed:
src/artifact/random-art-characteristics.cpp
src/flavor/object-flavor.cpp
src/inventory/inventory-curse.cpp
src/io/files-util.cpp
src/io/files-util.h
src/io/input-key-processor.cpp
src/monster-floor/monster-move.cpp
src/monster/monster-damage.cpp
src/monster/monster-describer.cpp
src/object-enchant/vorpal-weapon.cpp
src/player/player-damage.cpp
src/store/rumor.cpp

index 16a3759..f4d4b27 100644 (file)
@@ -153,14 +153,16 @@ std::string get_random_name(const ItemEntity &item, bool armour, int power)
     }
 
     auto filename = get_random_art_filename(armour, power);
-    char random_artifact_name[80]{};
-    (void)get_random_line(filename.data(), item.artifact_bias, random_artifact_name);
+    auto random_artifact_name = get_random_line(filename.data(), item.artifact_bias);
 #ifdef JP
-    if (random_artifact_name[0] == 0) {
-        return get_table_name();
+    if (random_artifact_name.has_value()) {
+        return random_artifact_name.value();
     }
+
+    return get_table_name();
+#else
+    return random_artifact_name.value();
 #endif
-    return random_artifact_name;
 }
 
 /*対邪平均ダメージの計算処理*/
index 01fd658..c57917a 100644 (file)
@@ -91,52 +91,43 @@ static bool object_easy_know(int i)
 }
 
 /*!
- * @brief 各種語彙からランダムな名前を作成する / Create a name from random parts.
+ * @brief 各種語彙からランダムな名前を作成する
  * @return std::string 作成した名前
  * @details 日本語の場合 aname_j.txt 英語の場合確率に応じて
- * syllables 配列と elvish.txt を組み合わせる。\n
+ * syllables 配列と elvish.txt を組み合わせる
  */
 std::string get_table_name_aux()
 {
-    std::string name;
+    std::stringstream ss;
 #ifdef JP
-    char syllable[80];
-    get_random_line("aname_j.txt", 1, syllable);
-    name = syllable;
-    get_random_line("aname_j.txt", 2, syllable);
-    name.append(syllable);
-    return name;
+    ss << get_random_line("aname_j.txt", 1).value();
+    ss << get_random_line("aname_j.txt", 2).value();
+    return ss.str();
 #else
-#define MAX_SYLLABLES 164 /* Used with scrolls (see below) */
-
-    static concptr syllables[MAX_SYLLABLES] = { "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek",
+    static std::vector<std::string_view> syllables = {
+        "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek",
         "bie", "bin", "bit", "bjor", "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf", "dan", "den", "der", "doe", "dok", "eep", "el", "eng",
         "er", "ere", "erk", "esh", "evs", "fa", "fid", "flit", "for", "fri", "fu", "gan", "gar", "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion",
         "ip", "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech", "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur", "nag", "nej",
         "nelg", "nep", "ner", "nes", "nis", "nih", "nin", "o", "od", "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po", "pot", "prok", "re",
         "rea", "rhov", "ri", "ro", "rog", "rok", "rol", "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna", "sne", "snik", "sno", "so", "sol", "sri",
         "sta", "sun", "ta", "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u", "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
-        "wed", "werg", "wex", "whon", "wun", "x", "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on", "foo", "ju", "xuxu" };
+        "wed", "werg", "wex", "whon", "wun", "x", "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on", "foo", "ju", "xuxu"
+    };
 
     int testcounter = randint1(3) + 1;
     if (randint1(3) == 2) {
         while (testcounter--) {
-            name.append(syllables[randint0(MAX_SYLLABLES)]);
+            ss << syllables[randint0(syllables.size())];
         }
     } else {
-        char syllable[80];
         testcounter = randint1(2) + 1;
         while (testcounter--) {
-<<<<<<< HEAD
-            (void)get_rnd_line("elvish.txt", 0, syllable);
-            name.append(syllable);
-=======
-            (void)get_random_line("elvish.txt", 0, syllable);
-            strcat(out_string, syllable);
->>>>>>> dd39ec10b ([Refactor] #2651 Renamed get_rnd_line() to get_random_line())
+            ss << get_random_line("elvish.txt", 0).value();
         }
     }
 
+    auto name = ss.str();
     name[0] = toupper(name[0]);
     return name;
 #endif
@@ -159,11 +150,10 @@ std::string get_table_name()
  */
 std::string get_table_sindarin_aux()
 {
-    char syllable[80];
-    get_random_line("sname.txt", 1, syllable);
-    std::string name = syllable;
-    get_random_line("sname.txt", 2, syllable);
-    name.append(syllable);
+    std::stringstream ss;
+    ss << get_random_line("sname.txt", 1).value();
+    ss << get_random_line("sname.txt", 2).value();
+    auto name = ss.str();
     return _(sindarin_to_kana(name), name);
 }
 
index bcd85f5..0f5a1a8 100644 (file)
@@ -34,6 +34,8 @@
 #include "util/quarks.h"
 #include "util/string-processor.h"
 #include "view/display-messages.h"
+#include <optional>
+#include <string>
 
 namespace {
 const EnumClassFlagGroup<CurseTraitType> TRC_P_FLAG_MASK({ CurseTraitType::TY_CURSE, CurseTraitType::DRAIN_EXP, CurseTraitType::ADD_L_CURSE, CurseTraitType::ADD_H_CURSE, CurseTraitType::CALL_ANIMAL, CurseTraitType::CALL_DEMON,
@@ -223,10 +225,11 @@ static void occur_chainsword_effect(PlayerType *player_ptr)
         return;
     }
 
-    char noise[1024];
-    if (!get_random_line(_("chainswd_j.txt", "chainswd.txt"), 0, noise)) {
-        msg_print(noise);
+    const auto noise = get_random_line(_("chainswd_j.txt", "chainswd.txt"), 0);
+    if (noise.has_value()) {
+        msg_print(noise.value());
     }
+
     disturb(player_ptr, false, false);
 }
 
index cc7ecdb..dc6d3cc 100644 (file)
@@ -91,24 +91,18 @@ errr file_character(PlayerType *player_ptr, concptr name)
 }
 
 /*!
- * @brief ファイルからランダムに行を一つ取得する /
- * Get a random line from a file
+ * @brief ファイルからランダムに行を一つ取得する
  * @param file_name ファイル名
  * @param entry 特定条件時のN:タグヘッダID
- * @param output 出力先の文字列参照ポインタ
- * @return エラーコード
- * @details
- * <pre>
- * Based on the monster speech patch by Matt Graham,
- * </pre>
+ * @return ファイルから取得した行 (但しファイルがなかったり異常値ならばnullopt)
  */
-errr get_random_line(concptr file_name, int entry, char *output)
+std::optional<std::string> get_random_line(concptr file_name, int entry)
 {
     char filename[1024];
     path_build(filename, sizeof(filename), ANGBAND_DIR_FILE, file_name);
     auto *fp = angband_fopen(filename, "r");
     if (!fp) {
-        return -1;
+        return std::nullopt;
     }
 
     int test;
@@ -117,7 +111,7 @@ errr get_random_line(concptr file_name, int entry, char *output)
         char buf[1024];
         if (angband_fgets(fp, buf, sizeof(buf)) != 0) {
             angband_fclose(fp);
-            return -1;
+            return std::nullopt;
         }
 
         line_num++;
@@ -128,7 +122,7 @@ errr get_random_line(concptr file_name, int entry, char *output)
         if (buf[2] == '*') {
             break;
         }
-        
+
         if (buf[2] == 'M') {
             if (monraces_info[i2enum<MonsterRaceId>(entry)].flags1 & RF1_MALE) {
                 break;
@@ -144,11 +138,12 @@ errr get_random_line(concptr file_name, int entry, char *output)
         } else {
             msg_format("Error in line %d of %s!", line_num, file_name);
             angband_fclose(fp);
-            return -1;
+            return std::nullopt;
         }
     }
 
     auto counter = 0;
+    std::string line{};
     while (true) {
         char buf[1024];
         while (true) {
@@ -170,14 +165,18 @@ errr get_random_line(concptr file_name, int entry, char *output)
         }
 
         if (one_in_(counter + 1)) {
-            strcpy(output, buf);
+            line = buf;
         }
 
         counter++;
     }
 
     angband_fclose(fp);
-    return counter ? 0 : -1;
+    if (counter > 0) {
+        return line;
+    }
+
+    return std::nullopt;
 }
 
 #ifdef JP
@@ -191,16 +190,16 @@ errr get_random_line(concptr file_name, int entry, char *output)
  */
 std::optional<std::string> get_random_line_ja_only(concptr file_name, int entry, int count)
 {
-    char line[1024]{};
+    std::optional<std::string> line;
     for (auto i = 0; i < count; i++) {
-        auto error = get_random_line(file_name, entry, line);
-        if (error) {
+        line = get_random_line(file_name, entry);
+        if (!line.has_value()) {
             return std::nullopt;
         }
 
         auto is_kanji = false;
-        for (auto j = 0; line[j]; j++) {
-            is_kanji |= iskanji(line[j]);
+        for (auto c = line.value().data(); *c != '\0'; c++) {
+            is_kanji |= iskanji(*c);
         }
 
         if (is_kanji) {
index 00dbe4e..85405d6 100644 (file)
@@ -27,7 +27,7 @@ class PlayerType;
 typedef void (*update_playtime_pf)(void);
 
 errr file_character(PlayerType *player_ptr, concptr name);
-errr get_random_line(concptr file_name, int entry, char *output);
+std::optional<std::string> get_random_line(concptr file_name, int entry);
 void read_dead_file(char *buf, size_t buf_size);
 
 #ifdef JP
index 0f9a655..da7dfc0 100644 (file)
@@ -95,6 +95,8 @@
 #include "window/display-sub-windows.h"
 #include "wizard/cmd-wizard.h"
 #include "world/world.h"
+#include <optional>
+#include <string>
 
 /*!
  * @brief ウィザードモードへの導入処理
@@ -681,10 +683,10 @@ void process_command(PlayerType *player_ptr)
             flush();
         }
         if (one_in_(2)) {
-            char error_m[1024];
             sound(SOUND_ILLEGAL);
-            if (!get_random_line(_("error_j.txt", "error.txt"), 0, error_m)) {
-                msg_print(error_m);
+            const auto error_mes = get_random_line(_("error_j.txt", "error.txt"), 0);
+            if (error_mes.has_value()) {
+                msg_print(error_mes.value());
             }
         } else {
             prt(_(" '?' でヘルプが表示されます。", "Type '?' for help."), 0, 0);
index 9d1cb38..abd6049 100644 (file)
@@ -536,15 +536,14 @@ void process_speak_sound(PlayerType *player_ptr, MONSTER_IDX m_idx, POSITION oy,
     }
 
     const auto m_name = m_ptr->ml ? monster_desc(player_ptr, m_ptr, 0) : std::string(_("それ", "It"));
-    char monmessage[1024];
-
     auto filename = get_speak_filename(m_ptr);
     if (filename.empty()) {
         return;
     }
 
-    if (get_random_line(filename.data(), enum2i(m_ptr->ap_r_idx), monmessage) == 0) {
-        msg_format(_("%^s%s", "%^s %s"), m_name.data(), monmessage);
+    const auto monmessage = get_random_line(filename.data(), enum2i(m_ptr->ap_r_idx));
+    if (monmessage.has_value()) {
+        msg_format(_("%^s%s", "%^s %s"), m_name.data(), monmessage->data());
     }
 }
 
index ea1fb9b..67eaf68 100644 (file)
@@ -48,6 +48,8 @@
 #include "view/display-messages.h"
 #include "world/world.h"
 #include <algorithm>
+#include <optional>
+#include <string>
 
 /*
  * @brief コンストラクタ
@@ -335,9 +337,9 @@ void MonsterDamageProcessor::dying_scream(std::string_view m_name)
         return;
     }
 
-    char line_got[1024];
-    if (!get_random_line(_("mondeath_j.txt", "mondeath.txt"), enum2i(m_ptr->r_idx), line_got)) {
-        msg_format("%^s %s", m_name, line_got);
+    const auto death_mes = get_random_line(_("mondeath_j.txt", "mondeath.txt"), enum2i(m_ptr->r_idx));
+    if (death_mes.has_value()) {
+        msg_format("%^s %s", m_name, death_mes->data());
     }
 
 #ifdef WORLD_SCORE
index c4772e5..9cc464f 100644 (file)
@@ -15,6 +15,9 @@
 #include "util/quarks.h"
 #include "util/string-processor.h"
 #include "view/display-messages.h"
+#include <optional>
+#include <string>
+#include <string_view>
 
 /*!
  * @brief モンスターの呼称を作成する / Build a string describing a monster in some way.
@@ -26,13 +29,14 @@ std::string monster_desc(PlayerType *player_ptr, MonsterEntity *m_ptr, BIT_FLAGS
 {
     MonsterRaceInfo *r_ptr;
     r_ptr = &monraces_info[m_ptr->ap_r_idx];
-    concptr name = (mode & MD_TRUE_NAME) ? m_ptr->get_real_r_ref().name.data() : r_ptr->name.data();
-    GAME_TEXT silly_name[1024];
+    std::string_view name = (mode & MD_TRUE_NAME) ? m_ptr->get_real_r_ref().name : r_ptr->name;
+    std::optional<std::string> silly_name;
     bool named = false;
     auto is_hallucinated = player_ptr->effects()->hallucination()->is_hallucinated();
     if (is_hallucinated && !(mode & MD_IGNORE_HALLU)) {
         if (one_in_(2)) {
-            if (!get_random_line(_("silly_j.txt", "silly.txt"), enum2i(m_ptr->r_idx), silly_name)) {
+            silly_name = get_random_line(_("silly_j.txt", "silly.txt"), enum2i(m_ptr->r_idx));
+            if (silly_name.has_value()) {
                 named = true;
             }
         }
@@ -45,10 +49,10 @@ std::string monster_desc(PlayerType *player_ptr, MonsterEntity *m_ptr, BIT_FLAGS
                 hallu_race = &monraces_info[r_idx];
             } while (hallu_race->name.empty() || hallu_race->kind_flags.has(MonsterKindType::UNIQUE));
 
-            strcpy(silly_name, (hallu_race->name.data()));
+            silly_name = hallu_race->name;
         }
 
-        name = silly_name;
+        name = silly_name.value();
     }
 
     bool seen = (m_ptr && ((mode & MD_ASSUME_VISIBLE) || (!(mode & MD_ASSUME_HIDDEN) && m_ptr->ml)));
@@ -164,16 +168,13 @@ std::string monster_desc(PlayerType *player_ptr, MonsterEntity *m_ptr, BIT_FLAGS
     std::string desc;
     if (m_ptr->is_pet() && !m_ptr->is_original_ap()) {
 #ifdef JP
-        char *t;
-        char buf[128];
-        strcpy(buf, name);
-        t = buf;
+        std::string buf(name);
+        auto *t = buf.data();
         while (strncmp(t, "』", 2) && *t) {
             t++;
         }
         if (*t) {
-            *t = '\0';
-            desc = format("%s?』", buf);
+            desc = format("%s?』", name);
         } else {
             desc = format("%s?", name);
         }
@@ -184,16 +185,13 @@ std::string monster_desc(PlayerType *player_ptr, MonsterEntity *m_ptr, BIT_FLAGS
         if (r_ptr->kind_flags.has(MonsterKindType::UNIQUE) && !(is_hallucinated && !(mode & MD_IGNORE_HALLU))) {
             if (m_ptr->mflag2.has(MonsterConstantFlagType::CHAMELEON) && !(mode & MD_TRUE_NAME)) {
 #ifdef JP
-                char *t;
-                char buf[128];
-                strcpy(buf, name);
-                t = buf;
+                std::string buf(name);
+                auto *t = buf.data();
                 while (strncmp(t, "』", 2) && *t) {
                     t++;
                 }
                 if (*t) {
-                    *t = '\0';
-                    desc = format("%s?』", buf);
+                    desc = format("%s?』", name);
                 } else {
                     desc = format("%s?", name);
                 }
index 8bf6892..f6252d1 100644 (file)
@@ -62,9 +62,9 @@ static void print_chainsword_noise(ItemEntity *o_ptr)
         return;
     }
 
-    char chainsword_noise[1024];
-    if (!get_random_line(_("chainswd_j.txt", "chainswd.txt"), 0, chainsword_noise)) {
-        msg_print(chainsword_noise);
+    const auto chainsword_noise = get_random_line(_("chainswd_j.txt", "chainswd.txt"), 0);
+    if (chainsword_noise.has_value()) {
+        msg_print(chainsword_noise.value());
     }
 }
 
index e7ff433..36c7b5d 100644 (file)
@@ -73,6 +73,8 @@
 #include "util/string-processor.h"
 #include "view/display-messages.h"
 #include "world/world.h"
+#include <sstream>
+#include <string>
 
 using dam_func = int (*)(PlayerType *player_ptr, int dam, concptr kb_str, bool aura);
 
@@ -295,9 +297,6 @@ int cold_dam(PlayerType *player_ptr, int dam, concptr kb_str, bool aura)
 int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_from)
 {
     int old_chp = player_ptr->chp;
-
-    char death_message[1024];
-
     int warning = (player_ptr->mhp * hitpoint_warn / 10);
     if (player_ptr->is_dead) {
         return 0;
@@ -475,19 +474,21 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr
 
                 msg_print(nullptr);
             } else {
+                std::optional<std::string> opt_death_message;
                 if (winning_seppuku) {
-                    get_random_line(_("seppuku_j.txt", "seppuku.txt"), 0, death_message);
+                    opt_death_message = get_random_line(_("seppuku_j.txt", "seppuku.txt"), 0);
                 } else {
-                    get_random_line(_("death_j.txt", "death.txt"), 0, death_message);
+                    opt_death_message = get_random_line(_("death_j.txt", "death.txt"), 0);
                 }
 
+                auto &death_message = opt_death_message.value();
                 do {
 #ifdef JP
-                    while (!get_string(winning_seppuku ? "辞世の句: " : "断末魔の叫び: ", death_message, sizeof(death_message))) {
+                    while (!get_string(winning_seppuku ? "辞世の句: " : "断末魔の叫び: ", death_message.data(), death_message.length())) {
                         ;
                     }
 #else
-                    while (!get_string("Last words: ", death_message, 1024)) {
+                    while (!get_string("Last words: ", death_message.data(), 1024)) {
                         ;
                     }
 #endif
@@ -495,12 +496,12 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr
 
                 if (death_message[0] == '\0') {
 #ifdef JP
-                    strcpy(death_message, format("あなたは%sました。", android ? "壊れ" : "死に").data());
+                    death_message = format("あなたは%sました。", android ? "壊れ" : "死に");
 #else
-                    strcpy(death_message, android ? "You are broken." : "You die.");
+                    death_message = android ? "You are broken." : "You die.";
 #endif
                 } else {
-                    player_ptr->last_message = string_make(death_message);
+                    player_ptr->last_message = string_make(death_message.data());
                 }
 
 #ifdef JP
@@ -510,9 +511,6 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr
                     int h = game_term->hgt;
                     int msg_pos_x[9] = { 5, 7, 9, 12, 14, 17, 19, 21, 23 };
                     int msg_pos_y[9] = { 3, 4, 5, 4, 5, 4, 5, 6, 4 };
-                    concptr str;
-                    char *str2;
-
                     term_clear();
 
                     /* 桜散る */
@@ -520,12 +518,12 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr
                         term_putstr(randint0(w / 2) * 2, randint0(h), 2, TERM_VIOLET, "υ");
                     }
 
-                    str = death_message;
+                    auto str = death_message.data();
                     if (strncmp(str, "「", 2) == 0) {
                         str += 2;
                     }
 
-                    str2 = angband_strstr(str, "」");
+                    auto *str2 = angband_strstr(str, "」");
                     if (str2 != nullptr) {
                         *str2 = '\0';
                     }
@@ -579,7 +577,11 @@ int take_hit(PlayerType *player_ptr, int damage_type, int damage, concptr hit_fr
                 hit_from = _("何か", "something");
             }
 
-            exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, std::string(_(hit_from, "was in a critical situation because of ")).append(_("によってピンチに陥った。", hit_from)).append(_("", ".")).data());
+            std::stringstream ss;
+            ss << _(hit_from, "was in a critical situation because of ");
+            ss << _("によってピンチに陥った。", hit_from);
+            ss << _("", ".");
+            exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, ss.str().data());
         }
 
         if (auto_more) {
@@ -632,7 +634,10 @@ static void process_aura_damage(MonsterEntity *m_ptr, PlayerType *player_ptr, bo
  */
 void touch_zap_player(MonsterEntity *m_ptr, PlayerType *player_ptr)
 {
-    process_aura_damage(m_ptr, player_ptr, has_immune_fire(player_ptr) != 0, MonsterAuraType::FIRE, fire_dam, _("突然とても熱くなった!", "You are suddenly very hot!"));
-    process_aura_damage(m_ptr, player_ptr, has_immune_cold(player_ptr) != 0, MonsterAuraType::COLD, cold_dam, _("突然とても寒くなった!", "You are suddenly very cold!"));
-    process_aura_damage(m_ptr, player_ptr, has_immune_elec(player_ptr) != 0, MonsterAuraType::ELEC, elec_dam, _("電撃をくらった!", "You get zapped!"));
+    constexpr auto fire_mes = _("突然とても熱くなった!", "You are suddenly very hot!");
+    constexpr auto cold_mes = _("突然とても寒くなった!", "You are suddenly very cold!");
+    constexpr auto elec_mes = _("電撃をくらった!", "You get zapped!");
+    process_aura_damage(m_ptr, player_ptr, has_immune_fire(player_ptr) != 0, MonsterAuraType::FIRE, fire_dam, fire_mes);
+    process_aura_damage(m_ptr, player_ptr, has_immune_cold(player_ptr) != 0, MonsterAuraType::COLD, cold_dam, cold_mes);
+    process_aura_damage(m_ptr, player_ptr, has_immune_elec(player_ptr) != 0, MonsterAuraType::ELEC, elec_dam, elec_mes);
 }
index 76c15de..f81a3cb 100644 (file)
@@ -94,25 +94,20 @@ static std::pair<FixedArtifactId, const ArtifactType *> get_artifact_definition(
 void display_rumor(PlayerType *player_ptr, bool ex)
 {
     int section = (ex && (randint0(3) == 0)) ? 1 : 0;
-    char rumor[1024]{};
-
-    // @todo「嘘の噂もある。」は後で統合するため日英分離しない.
 #ifdef JP
-    auto tmp_rumor = get_random_line_ja_only("rumors_j.txt", section, 10);
-    if (tmp_rumor.has_value()) {
-        strcpy(rumor, tmp_rumor.value().data());
-    } else {
-        strcpy(rumor, _("嘘の噂もある。", "Some rumors are wrong."));
-    }
+    auto opt_rumor = get_random_line_ja_only("rumors_j.txt", section, 10);
 #else
-    errr err = get_random_line("rumors.txt", section, rumor);
-    if (err) {
-        strcpy(rumor, _("嘘の噂もある。", "Some rumors are wrong."));
-    }
+    auto opt_rumor = get_random_line("rumors.txt", section);
 #endif
+    std::string rumor;
+    if (opt_rumor.has_value()) {
+        rumor = opt_rumor.value().data();
+    } else {
+        rumor = _("嘘の噂もある。", "Some rumors are wrong.");
+    }
 
-    if (strncmp(rumor, "R:", 2) != 0) {
-        msg_format("%s", rumor);
+    if (strncmp(rumor.data(), "R:", 2) != 0) {
+        msg_print(rumor);
         return;
     }