2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C流、C++流の入出力メモ(printf, sprintf, fprintf)

Last updated at Posted at 2019-04-07

はじめに

C言語、C++言語での入出力方法(標準・ファイル)について忘れないためにメモを残す。
サンプルコードをいくつか載せますが、決してスマートなコードではありません。あくまで比較しやすいように書いています。それと、メモなので説明は少ないです。

環境

  • Cygwin (ver. 3.05)
  • gcc (ver. 7.4.0)

printf VS cout

printf.cpp
#include <iostream>

using namespace std;

int main(){
    int n(10);

    // C
    printf("C\n");
    printf("%d\n", n);

    //C++
    cout << "C++" << endl;
    cout << n << endl;

    return 0;

}

出力結果

C
10
C++
10

sprintf VS stringstream

 ostringstreamじゃなくて、stringstreamでもいいけど、
今回は、istringstreamの機能は使わないため、ostringstreamを採用。

sprintf.cpp
#include <iostream>
#include <sstream> // for ostringstream

using namespace std;

int main(){
    int n(10);

    // C
    char str[10];
    printf("C\n");
    sprintf(str, "str = %d", n);
    printf("%s\n", str);

    //C++
    ostringstream oss;
    oss << "str = " << n;
    cout << "C++" << endl;
    cout << oss.str() << endl;

    return 0;

}

出力結果


C
str = 10
C++
str = 10

fscanf & fprintf VS ifstream & ofstream

 入力ファイルとして以下を用意。3行目には、行頭に2スペース挿入。

sample.dat
aaa bbb
123 456 679
  12 22

続いて、CとC++の比較用コード

fprintf.cpp
#include <iostream>
#include <fstream>

using namespace std;

int main(){

    // C
    char str1[10], str2[10];
    FILE *ifile, *ofile;
    int int1, int2, int3, int4, int5;
    ifile = fopen("sample.dat", "r");
    ofile = fopen("sample.dat.out.C", "w");
    fscanf(ifile, "%s %s", str1, str2);
    fscanf(ifile, "%d %d %d", &int1, &int2, &int3);
    fscanf(ifile, "%d %d", &int4, &int5);

    fprintf(ofile, "1: %s %s\n", str1, str2);
    fprintf(ofile, "2: %d %d %d\n", int1, int2, int3);
    fprintf(ofile, "3: %d %d\n", int4, int5);

    fclose(ifile);
    fclose(ofile);

    //C++
    ifstream ifs;
    ofstream ofs;

    char st1[10], st2[10];
    int in1, in2, in3, in4, in5;

    ifs.open("sample.dat");
    ofs.open("sample.dat.out.Cplus");

    ifs >> st1 >> st2;
    ifs >> in1 >> in2 >> in3;
    ifs >> in4 >> in5;

    ofs << "1: " << st1 << " " << st2 << endl;
    ofs << "2: " << in1 << " " << in2 << " " << in3 << endl;
    ofs << "3: " << in4 << " " << in5 << endl;

    ifs.close();
    ofs.close();

    return 0;

}

出力結果

sample.dat.out.[C|Cplus]
1: aaa bbb
2: 123 456 679
3: 12 22

空白はうまいこと扱ってくれる。C++の方では、charではなくstringを使った方が安全だけど、対照実験のためcharを使用。

所感

 結構C++のコードでも、while + getline + sscanfで変数への代入をやっているものを見かけるけど、個人的にはifstreamから直接代入する方が楽かなーと思いました。
 私は行によってコラム数が変わるようなデータを扱うこともあるので、後者の方法を良く使うことになりそう。
逆にループ回数の情報を、ファイルのヘッダーや外部の情報から得ることができない場合は、前者を使うことになるのかな。

その他

  • 何か間違いがあれば、ご指摘いただけると幸いです。
2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?