teratail header banner
teratail header banner
質問するログイン新規登録

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

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

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

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

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

Q&A

0回答

294閲覧

_stprintf_sの挙動について

torion

総合スコア0

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

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

0グッド

0クリップ

投稿2025/06/02 02:44

編集2025/06/02 06:18

0

0

Visual C++(Visual Studio 2022)で開発を行っています

Win10環境で動作していたプログラムがあり、今回OSをWindows11に更新して動作を確認したところ
カレントディレクトリとiniファイル名称を結合する処理がうまくいかなくなっていました。
具体的には以下のような処理となっています。
なお、プロジェクトで「Unicode 文字セットを使用する」にしています。

#define INI_FILE_NAME _T("TEST.ini") // iniファイル名 TCHAR lpTcCurDir[1024]; // カレントディレクトリ TCHAR lpTcIniFilePath[1024]; // iniファイルのフルパス GetCurrentDirectory(1024, lpTcCurDir); // カレントディレクトリ取得 _stprintf_s(lpTcIniFilePath, _T("%s\\%s"), lpTcCurDir, INI_FILE_NAME); //パスの結合

前述のとおりプロジェクトで「Unicode 文字セットを使用する」に設定しており、TCHARはワイド文字列扱いとなっているので、試しに以下の通り%sの部分を%lsに変更したところうまく動作しました。

_stprintf_s(lpTcIniFilePath, _T("%ls\\%ls"), lpTcCurDir, INI_FILE_NAME);

動作するようにはなったのですが2点疑問に思い、わかる方がいればご教授願いたく思います。
(1)前環境(Windows10)ではなぜ動作していたのか
(2)_T("%s")の部分は「Unicode 文字セットを使用する」にしていれば自動的に%lsとして扱われないのか

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

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

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

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

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

TakaiY

2025/06/02 04:24

> このサイトでは\が連続すると1つとして扱われている そういう問題を避けるには、編集時に出てくる </>(コードの挿入)ボタンを押して出てくる書式に沿ってコードを記述するといいでしょう。 質問は編集できます。
int32_t

2025/06/02 05:04

%sはTCHAR文字列を受け取るので%lsにする必要はない、で合ってると思います。 質問文に書いてないコードの問題の可能性が高い気がします。 > 結合する処理がうまくいかなくなっていました。 具体的にはどうなってしまうのでしょうか。 WIndows 10で動いていた実行ファイルそのままがWindows 11での実行で問題が発生したのでしょうか。
torion

2025/06/02 06:34

TakaiY様 ご指摘ありがとうございます コード挿入機能に変更しました
torion

2025/06/02 06:51

int32_t様 例えば、Windows11環境でC:\abc\binに実行ファイルを置いて実行した場合、_stprintf_s()の結果が"C\\T"となります。 Cドライブの"C"とTEST.iniの"T"だけが結合されているような挙動に思えます。 ちなみに#define INI_FILE_NAME _T("TEST.ini")を #define INI_FILE_NAME _T("XYZ.ini")とした場合は結果が"C\\X"となりました。 Windows 10で動いていた当時の実行ファイルをそのまま実行しており、iniファイルが読めていないようなソフトウェアの挙動をしていたのでこの事象の発見に至りました。
matukeso

2025/06/02 07:52

どこかで_CRT_STDIO_ISO_WIDE_SPECIFIERSあたりがdefineされているとか?
torion

2025/06/02 12:16

matukeso様 ご指摘ありがとうございます。 おかげさまで理解が深まりました。 ご指摘の件で調べてみたところある記事を見つけました。 Visual C++ で、例えばwprintf に %s と %c を指定した場合、wchar_tとして 扱われるのはVisual C++ の独自仕様で、C/C++ の規格上は、wprintf などの wchar_t 系の関数であっても、wchar_t を扱いたい場合は、%ls を使う必要があるということを初めて知りました。 調べた記事ではwprintfに言及していましたが_stprintf_sもこの独自仕様に沿っていると考えれば_T("%s")としていることはVC++では問題ないという認識でおります。 また、VC2015あたりで、_CRT_STDIO_ISO_WIDE_SPECIFIERSを定義するとこれらがC/C++ 標準規格の動作をするよう仕様変更されたとも記述がありました。 ここまでのことでご指摘を踏まえ改めて考えたところ、_T("%ls")としたらうまく動作したということはC/C++ 標準規格の動作となっているので、_CRT_STDIO_ISO_WIDE_SPECIFIERSが定義されているのではないかというご指摘と理解しました。 そのため_CRT_STDIO_ISO_WIDE_SPECIFIERSの定義を探したのですが、ソースコード上は見つけられませんでした。プロジェクトの設定によって変更ができるのか調べ中です。 ただ話の筋道としてはかなり合点がいくのでこのあたりに何か糸口がないかもう少し考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問