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

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

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

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

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

Q&A

解決済

1回答

1284閲覧

vsnprintfの第2引数のために書式と引数から事前に文字数だけを知る方法

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

0グッド

1クリップ

投稿2021/10/21 07:52

編集2021/10/21 07:53

vsnprintfに可変長引数リストの他に書式も変数で与えたいのですが、第2引数のバッファに書き込まれるバイト数を可変長引数リストと書式から

1.vsnprintfを実行する前に
2.最大値などではなく正確に
3.バッファオーバーランなどのリスクなく安全な関数・方法で
4.一から書式を解釈する処理を書くことなく

取得できるような都合の良い方法はないでしょうか?

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

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

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

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

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

jimbe

2021/10/21 08:07

vsnprintf を実行すれば必要な大きさが分かりますのに、なぜ 1 がダメなのでしょうか。
退会済みユーザー

退会済みユーザー

2021/10/21 08:28

ありがとうございます。 ただ、int32_t さんに回答したような問題を確認しました。 回避方法ご存じでしょうか?
退会済みユーザー

退会済みユーザー

2021/10/21 08:32

Bullさん、ありがとうございます。 今現在はVisual Studio2019で実行しています。 ただこれは暫定で最終的にはどこかでソースファイルを取得して、H8マイコンに移植するのが目的です。 _vscprintfのソースが容易に見つけられるようなら検討したいと思います。
guest

回答1

0

ベストアンサー

vsnprintf()の実行に必要なバッファサイズを事前に計算するのが、同じくvsnprintf()です。

一度 vsnprintf(NULL, 0, ... でサイズを計算してからバッファを確保して再実行すればよいです。

投稿2021/10/21 08:14

int32_t

総合スコア21695

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

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

退会済みユーザー

退会済みユーザー

2021/10/21 08:26

ありがとうございます。 実際に試したところそんなほぼそのような動作になりました。 下記のサイトように間違っていたり、曖昧な説明をしているところも多いんですね。 ttps://programming-place.net/ppp/contents/c/appendix/reference/vsnprintf.html ttps://www.ibm.com/docs/ja/i/7.1?topic=ssw_ibm_i_71/rtref/vsnprintf.htm で、「ほぼ」の部分なのですが・・・改行\nが入っていると戻り値が+1じゃなく+2増えるんですね・・・。これだと実際に戻り値を戻して実行すると1多くなってしまうのですが、回避策ありますでしょうか?
int32_t

2021/10/21 08:29

> +1じゃなく+2増える 私はそのような現象は見たことがありません。 詳細を書いて別の質問にしてはいかがでしょうか。
dodox86

2021/10/21 08:39

> 改行\nが入っていると戻り値が+1じゃなく+2増えるんですね・・・。 "\n"が"\x0a"だけではなく、Windows用に"\x0d\x0a"に変換される環境でやっていませんか。
jimbe

2021/10/21 08:40

改行コードの差ではないでしょうか。
退会済みユーザー

退会済みユーザー

2021/10/21 08:53

たくさん回答ありがとうございます。 改行コードの違いかと少し調べてみたのですが・・・ ``` #include <stdio.h> #include <stdarg.h> int vout(char* string, char* fmt, ...) { int ret = 0; va_list arg_ptr; va_start(arg_ptr, fmt); ret = vsnprintf(string, vsnprintf(string, 0, fmt, arg_ptr) + 1, fmt, arg_ptr); va_end(arg_ptr); return ret; } int vout2(char* string, char* fmt, ...) { int ret = 0; va_list arg_ptr; va_start(arg_ptr, fmt); ret = vsnprintf(string, 6, fmt, arg_ptr); va_end(arg_ptr); return ret; } int main() { char fmt1[] = "%s"; char fmt2[] = "%s¥n"; char string[128] = {0}; int ret = 0; ret = vout(string, fmt1, "Hello"); printf("%s, %d\n", string, ret); ret = vout(string, fmt2, "Hello"); printf("%s, %d\n", string, ret); ret = vout2(string, fmt2, "Hello"); printf("%s, %d\n", string, ret); } ``` 結果 Hello, 5 Hello?n, 7 Hello, 7 2行目は第二引数も文字数が多いのか、?nという変な文字が出てしまっています。 デバッガでステップ実行しながらstringの中身を見る限り、0d0aにはなっていませんでした。
退会済みユーザー

退会済みユーザー

2021/10/21 08:54

すいません。 回答コメントでは```が効かないんですね・・・失礼しました。
int32_t

2021/10/21 08:55

> "%s¥n"; バックスラッシュではなく円マークになってますよ。
dodox86

2021/10/21 09:01

int32_t さんのご指摘が当たり、ですね。 リテラル文字列でのコンパイル時の自動変換の問題かと思いましたが、Visual Studio 2019 C言語ソース、マルチバイト文字でのビルドだとちゃんと"\n"="\x0a"でした。 #include <stdio.h> #include <string.h> int main() { const char s[] = "1234\n"; printf("len=%d\n", strlen(s)); for (const char* ps = s; *ps != '\0'; ++ps) { printf("%02X ", *ps); } printf("\n"); } 実行結果: len=5 31 32 33 34 0A
退会済みユーザー

退会済みユーザー

2021/10/21 09:09

ありがとうございます。 ご指摘の通りソースコードをUnicodeにしたら想定した動きになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問