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

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

ただいまの
回答率

90.52%

  • C

    3687questions

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

  • C++

    3450questions

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

C++でC言語の関数を利用する時

受付中

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 614

strike1217

score 554

C++でC言語の関数を利用する時って結構ありますか??
自分は、Linux系のプログラミングをしていると良くあります。

例えば・・・printf関数とかは結構使いますかね。
C++でC言語の関数を利用していると困ることが時々あります。

STLとC言語関数の連携と型についてです。
2016年、C言語はどう書くべきか (前編)

新しいコードに、char、int、short、long、unsignedなどの型を使おうとしているなら、それは誤りです。

charはもう使わないので注意してください。実際、C言語ではcharは誤った名称で誤った使い方をされています。

    std::string text = "Hello!!";
    std::cout << text << std::endl;
    std::printf("%s\n", text.c_str());


std::stringのc_str()関数ってchar型のポインタですよね。
char使ってるんですが・・・こういうのはどうするんでしょう??

「std::coutを使いたくない」という方は結構いるのではないでしょうか?
STLと連携を取るなら、std::coutの方が良さそうですが・・・
自分は、printfの方が使いやすいですね。

他にも、最近問題となったのが、mmap()とstd::fstream との連携ができなく結局fopen関数を使う羽目に・・・・なったり

ん〜〜〜。

正直C++でC言語の関数を使わない方が良いんでしょうか??
しかし、C言語の大量の関数群をC++でも使いたい!からC言語の上位互換として開発したものなんですよね?
使えないとC言語の上位互換という位置づけでは無くなりそうですね。

関数のパラメータ用にSTLコンテナから要素を取り出し、いちいち型を変換しなくてはいけないのが、かなり面倒です。

皆さんはどのようにして問題を回避しているのでしょうか?
ぜひ教えてください。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+7

 回答

それは元記事の内容をだいぶ歪めた理解と言うことができます(元記事のミスリードもひどいけど)。

新しいコードに、char、int、short、long、unsignedなどの型を使おうとしているなら、それは誤りです。 

とは 整数を格納する型として と捉えるべきです。文字列、ただし一単位が1byteな文字エンコードを格納する型としては、これまで通りchar型を用いるべきです。


文字列についてはC11/C++11にてUnicode周りの大きな改善(不十分)が追加されたことを知っておくべきです。

まずこれまで

文字リテラル 格納される物
'' char 実装依存
L'' wchar_t 実装依存(一文字を表すのに十分な大きさの型とあるが、これは実現不可能、UTF-16かUTF-32が現実には使われる

がありましたが、Unicode対応のため

文字リテラル 格納される物
u'' char16_t UTF-16
U'' char32_t UTF-32

が追加されました。同様に文字列リテラルも存在します。

文字列リテラルに限ってはC11/C++11で

文字列リテラル 格納される物
u8"" const char[] UTF-8

が追加されています。

またC++17では

文字リテラル 格納される物
u8'' char UTF-8

が追加されています(C言語でどうだったか覚えてない)

ここで重要なこととして、C/C++にはなんとまさかのUTF-8を保証する型が存在しません。

https://cpplover.blogspot.com/2016/09/c-p0370r1-p0379r0.html
C++11のときにchar8_tが必要だと訴えたら、charは古典的にバイト列を表現する型なので十分だ。char型以外の型があるのは混乱する。などと理解のないUnicodeの世界に生きていない名だたる委員達から散々に批判された。その委員達も、今では、「やっぱりchar8_tがないのは失敗だったなぁ」とぼやいている。それ見たことか。 

C++11で文字の何たるかを理解できないアスキー文字しか解さないクソどもがUTF-8を保証するchar8_t型をRejectしたからです。

C++17で再び提案されるもやはりReject。

C/C++標準化委員会の連中は全く文字の何たるかを理解できないと言うことができます。

さて、C++20に向けて再びchar8_t型が提案されています

もしchar8_t型が標準入りしたならば、もはやcharは使うべきではないと言えるでしょう。


整数型について、stdint.h/cstdintヘッダーに定義されるintN_t型を用いよ、という主張は正しいと言えなくもないです。大きさが明確に定まっているべきbinary formatに対応する構造体/trivialy copyable classの要素型であるとか、他の言語から使われることを想定するC APIなどは必ずこれを用いるべきです。またそうでない場合も2の補数系を仮定できるとか1byte=8bitを仮定できるなど考えうことが減り、たかが差の絶対値を計算するのに
C/C++はnull安全になる前に安全に差の絶対値を計算できるようになるべきではないか - Qiita#つまり安全に差の絶対値を計算できるようにはどうすればいいのか
のようなコードを書かずに済んだりと恩恵があります。


話がそれました。戻しましょう。

正直C++でC言語の関数を使わない方が良いんでしょうか??

C++に便利な関数群が十分存在していてそのほうが楽だからそちらを使う、ただそれだけのことです。

ご自分でも

関数のパラメータ用にSTLコンテナから要素を取り出し、いちいち型を変換しなくてはいけないのが、かなり面倒です。 

と書かれているじゃないですか。プログラマーは怠惰であるべきなので、STLを使うほうが楽できます。STLの関数群/クラス群の使い方を調べるには
https://cpprefjp.github.io/
が便利です(宣伝)

ただしiostream系はC++のstd::coutのようなスタイルやCのprintfのようなスタイルともに明らかな問題が存在し、fmtlib/fmtとかを使うべきだということができます。またlocaleはだいたいC/C++問わずぶっ壊れていて使い物になりません

 以下余談。

std::stringのc_str()関数ってchar型のポインタですよね。

違います。const修飾されている=const char *です。C++はconst性についてかなり厳密に扱います。


C/C++にはUnicodeどうしの文字コード変換を行う方法が存在しないという状態が生じています(C++11で入ったが致命的な欠陥が見つかってC++17でdeprecated)


C APIで文字列を受け取る場合のAPI設計について留意するべきことがあります。

Cだけやっていると

void foo(char* str);

のようなAPIを作りがちですが、2つの点からこれをするべきではありません。

  1. 文字列の長さがNULL終端文字に依存している  
    Cでは文字列とはNULL終端するbyte列のことでしたが、これはプログラミングをする上で余計なメモリ確保を強いる事があり、非効率的です。  
    C++ですらC++17でstring_viewなるものが追加され、文字列の先頭へのポインタと長さの構造体のようなクラスをstd::stringと同じインターフェースで扱えるようになったことでNULL終端しない文字列を扱う機会が増えます。

  2. const修飾されていない  
    const修飾されていないとC++ではこのAPIに文字列リテラルを渡すことができません。  
    また文字列が書き換えられる可能性があるため安全のために一度動的メモリ確保を行いコピーするコストが発生し、著しく実行速度に影響を与えます。

したがって

void foo(const char* str, size_t len);

のようにしましょう。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/08 02:19

    おお、UTF-8を保証する型が粘り強く提案されているのですね!! 頑張れ! char8_t。
    u8""の文字の型がchar8_tになるのも嬉しいですね。
    ついでに u8string u8str=u16string(L"xyz"); などもできるようになると嬉しいけど、提案はされてないっぽい?(operator=をフリー関数で定義できないから、厳しそうな気がする。)

    キャンセル

  • 2018/07/08 10:54

    std::codecvtの特殊化は同文章で提案されてるんですけどねぇ・・・。Unicode同士の変換は提案されてないと思いますが、filesystemみたいなbreaking changeを要求するクソ仕様を無理やり入れるんじゃなくてchar8_tを入れるのが先でしょうね。

    キャンセル

  • 2018/07/08 14:55

    yumetodo様はC言語の関数をC++で利用する場面ってあるんでしょうか?
    ほとんどないですかね?

    キャンセル

  • 2018/07/08 22:25 編集

    私はライブラリを作って遊んでいる人間なので、template対応させるのが面倒なC標準の関数は呼ばないですね・・・。例えば文字列操作はCの関数ではなくstd::char_trais以下の関数のほうがtemplate対応しやすいです。ただしC++20がまだ来ないのでカレンダー周りやるときはtm構造体などは触りますがChironianさん指摘の通りそうとうだるい・・・。

    C APIな外部ライブラリは普通に使いますよ。

    標準入出力についてはCで正しく標準入出力を扱うのはC++のtemplateでメタプログラミングするよりも難しいので自分には無理です、というかあれは人間には無理。

    キャンセル

  • 2018/07/08 22:33

    printfが恋しくなったらそうじゃなくってfmtlib/fmtを検討してみてください。圧倒的に恋に落ちる。私が本当に欲しかったもの感ある。

    キャンセル

  • 2018/07/23 19:53

    C++ Now and TomorrowでBjarne Stroustrup氏になぜchar8_t型がないのか聞いてきた
    https://qiita.com/yumetodo/items/2f2d95e8fabd78a5d0c8

    キャンセル

  • 2018/07/24 19:15

    C++ Now and Tomorrow
    というものがあるんですか!
    初めて知りました。
    素晴らしいですね!

    キャンセル

+5

こんにちは。

そのリンク先は結構話題になります
内容については玉石混淆って感じですね。あまり気にしない方が良いかも知れません。

正直C++でC言語の関数を使わない方が良いんでしょうか??

同様な機能があるものについてはC++を使った方が生産性は上がり易いです。しかし、当然学習コストがかかるので悩ましい部分はあります。

私もずいぶん長い間printf系を使ってました。
でも、iostreamに慣れた今は勿体無いかったと感じます。ログ・ツールをvsnprintfで無茶苦茶苦労して作ってましたが、std::stringstreamなら超簡単ですし。
整形出力を頻繁に使うなら、boost::formatは便利ですよ。%演算子がちょっと鬱陶しいですけどね。

また、カレンダー系は未だサポートされていませんのでC言語の関数を未だに使うしかないです。(マルチスレッド対応版は、gccとmsvcと標準規格の全てが異なっているのでマジ頭痛かったですが、背に腹は変えられません。)
C++2aでやっとサポートの見込みのようです。ダメダメだったカレンダーがまともになりそうですけど、<chrono>は使い方が難しいのが難点です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/08 10:58 編集

    ><chrono>は使い方が難しい

    今は慣れたし論理的でわかりやすいと感じるけど、勉強してた頃は江添さんの解説記事をにらめっこしながら書いてたなぁ・・・。
    ただC++11で入ったchronoのtime_pointとdurationの分離はRustでもそうだし、C++固有の概念でもないので、ぜひとも身につけたいところ。

    キャンセル

  • 2018/07/08 14:51

    C言語の関数を利用する場面というのはほとんどないんですか?

    キャンセル

  • 2018/07/08 15:31

    まだベターCとしてC++を使っていた頃は頻繁に使ってましたよ。
    C言語に比べると設計が新しい分よく練り込まれているので、C++を真面目に勉強し始めてからはC++のライブラリを使うことが増えました。(とは言っても既に古臭くなっているものも残ってます。特にiostream。更新されることを祈ってます。)

    キャンセル

  • 2018/07/08 18:11

    C++はC言語の機能受け継ぐ必要性ってあったんですか?
    新たにC++用の関数を作るならC言語の機能いらなくないですよね?
    C言語とは分けて考えるべきですかね。

    キャンセル

  • 2018/07/08 18:41

    > C++はC言語の機能受け継ぐ必要性ってあったんですか?
    ありますよ。互換性は非常に重要ですから。

    また、C++のライブラリの使い方が難しいことはご存知の通りと思います。
    Cライブラリを一切使えなくしたら、C++のライブラリの使い方をある程度悟るまでC++を使えません。
    それよりは、Cライブラリも使えるようにしておき、少しづつでも悟った機能から使えばよいというのはたいへんありがたいですよ。

    キャンセル

  • 2018/07/08 20:43

    ああ!なるほど!そういう考え方ですか!

    キャンセル

  • 2018/07/08 22:30

    > C++はC言語の機能受け継ぐ必要性ってあったんですか?

    FFIをC++に持ってきて互換を切ってしまったらもはやC++に存在価値がないですね、それくらいならRust使う。

    C標準ライブラリはC++的にはどうでもいいですが、Cのコア言語機能は負の側面があるにもかかわらず維持しなければならない絶対ラインです。

    キャンセル

  • 2018/07/08 22:34 編集

    「FFIをC++に持ってきて互換を切ってしまったらもはやC++に存在価値がない」
    なるほど。重要なのはライブラリの方ではないんですね。

    キャンセル

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

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3687questions

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

  • C++

    3450questions

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