2017-12-14 16 views
1

次のコードを考えてみてください:printf文字(%c、%d)を関数の引数として渡す方法はありますか?

#include <stdio.h> 

void printStrGeneric(void *, int, int); 
void printNumGeneric(void *, int, int); 

int main() 
{ 

    int intArray[] = { 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85 }; 

    printNumGeneric(intArray, sizeof(intArray), sizeof(int)); 
    printStrGeneric(intArray, sizeof(intArray), sizeof(int)); 
    puts(""); 

    short shortArray[] = { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74 }; 

    printNumGeneric(shortArray, sizeof(shortArray), sizeof(short)); 
    printStrGeneric(shortArray, sizeof(shortArray), sizeof(short)); 
    puts(""); 

    return 0; 
} 

void printStrGeneric(void *object, int size, int elem_size) 
{ 
    char *p = (char *) object; 
    while (p < (char *) object + size) { 
     printf("%c\t", *p); 
     p += elem_size; 
    } 
    puts(""); 
} 

void printNumGeneric(void *object, int size, int elem_size) 
{ 
    char *p = (char *) object; 
    while (p < (char *) object + size) { 
     printf("%d\t", *p); 
     p += elem_size; 
    } 
    puts(""); 
} 

- 機能printStrGenericprintNumGenericは(printf文字を除く)はほぼ同一であることを考えると、私は、それだけではなく、1機能を持たせることができ、任意の方法であるかどうかを疑問に思います関数に引数としてprintf文字(%cまたは%dのいずれか)を渡しますか?

+4

はい。書式指定子は単なる文字列です。これをパラメータとして関数 – OldProgrammer

+1

に渡すことは可能ですが、フォーマット文字列に文字列リテラル以外のものを使用すると[セキュリティ上の脆弱性](https://en.wikipedia.org/wiki/Uncontrolled_format_string) )。 – 0x5453

+3

引数がプログラマから来ている限り、私はそれが最初からprintfよりもセキュリティ上のホールではないことはわかりません。 printfの実際のセキュリティ問題は、ユーザーが取得した文字列を書式文字列として渡すことに由来します。 – SoronelHaetir

答えて

2

読むの使用について:

  1. va_args

  2. の構文:形式、...

これらの2つの組み合わせによって、関数に書式を渡して、望むように処理することができます。

これは非常に簡単な説明です。https://www.eskimo.com/~scs/cclass/int/sx11b.html

+1

これは、2つの形式の簡単な選択のためには過剰です。特に、脆弱性を避けるためには、初心者にとってかなりの労力が必要です。 [Saravana Kumar]の[answer](https://stackoverflow.com/a/47822866/298225)(https://stackoverflow.com/users/6162823/saravana-kumar)は、より適切な即時解決策です。さらに、実際の解決策を提示するものでもなく、解決策を見つけるために調査する情報を参照するだけです。 –

+0

これは本当に問題に対処していないようです。 – Gerhardh

2

引数としてフォーマット指定子を渡すことは@OldProgrammerのように行う方法の1つですが、@ 0x5453のように脆弱性が指摘されます。

bool値を余分なパラメータとして渡したり、if条件を使ってprintf関数を制御したりしていませんか?だからあなたのコードは次のようになります。

void printGeneric(void *object, int size, int elem_size, bool str) 
{ 
    char *p = (char *) object; 
    if(str){ 
     while (p < (char *) object + size) { 
      printf("%c\t", *p); 
      p += elem_size; 
     } 
    }else{ 
     while (p < (char *) object + size) { 
      printf("%d\t", *p); 
      p += elem_size; 
     } 
    } 
    puts(""); 
} 
+0

簡略化することができます: 'char * fmt = str? "%c \ t": "%d \ t"; 'このポインタを' printf'で使用し、 'if'をドロップしてください。 – Gerhardh

関連する問題