2017-01-09 21 views
0

私は構造体をC言語で学習していますが、深夜であるかどうかをテストするために構造体に到達する便利な方法はわかりません。Cで構造体を比較

ラインが構文エラー(error: expected expression)を持っている "場合":

struct date 
{ 
    int month; 
    int day; 
    int year; 
}; 
struct time 
{ 
    int hour; 
    int minutes; 
    int seconds; 
}; 

struct dateAndTime 
{ 
    struct date sdate; 
    struct time stime; 
}; 

struct dateAndTime clockKeeper(struct dateAndTime DaT) 
{ 
    struct dateAndTime UpdatedDaT = { .stime = timeUpdate(DaT.stime) }; 

    if (UpdatedDaT.stime == { 0, 0, 0})// If midnight 
     UpdatedDaT.sdate = dateUpdate(DaT.sdate); 
    else 
     UpdatedDaT.sdate = DaT.sdate; 

    return UpdatedDaT; 
} 
int main(void) 
{ 
    struct dateAndTime DaT; 
    printf("Enter date and time (mm dd yyyy hh:mm:ss): "); 
    scanf("%i %i %i %i:%i:%i", &DaT.sdate.month, &DaT.sdate.day, &DaT.sdate.year, 
     &DaT.stime.hour, &DaT.stime.minutes, &DaT.stime.seconds); 

    struct dateAndTime UpdatedDaT = clockKeeper(DaT); 

    printf("\nThe UpdatedDaT is %i/%i/%.2i %.2i:%.2i:%.2i\n", 
     UpdatedDaT.sdate.month, UpdatedDaT.sdate.day, UpdatedDaT.sdate.year, 
     UpdatedDaT.stime.hour, UpdatedDaT.stime.minutes, UpdatedDaT.stime.seconds); 

    return 0; 
} 

答えて

2

有効なCの文法ではありません - あなただけの構造体を比較することができます:ここでは

if (UpdatedDaT.stime == { 0, 0, 0})// If midnight 
     UpdatedDaT.sdate = dateUpdate(DaT.sdate) 

は私のプログラムからいくつかのコードです要素ごとに

変更:

if (UpdatedDaT.stime == { 0, 0, 0})// If midnight 

へ:

if (UpdatedDaT.stime.hour == 0 && 
    UpdatedDaT.stime.minutes == 0 && 
    UpdatedDaT.stime.seconds == 0)// If midnight 
+1

ありがとう! @Paul R – Yellowfun

1

より便利な方法は、memcmp

まず、すなわち、機能を比較するメモリを使用する定義し、使用されるデフォルトの変数を初期化することですこのような他のデータをチェックするために

/* To zero out everything */ 
memset(DefaultDaT, 0, sizeof(DefaultDaT)); 
memset(UpdatedDaT, 0, sizeof(UpdatedDaT)); 

DefaultDaT.stime.hour = 0; 
DefaultDaT.stime.minutes = 0; 
DefaultDaT.stime.seconds =0; 

その後は、単にあなたが==と構造を比較することはできません(また、あなたがmemcmpを使用する必要があります)この

よう
if (memcmp(DefaultDaT, UpdatedDaT, sizeof(DefaultDaT)) == 0) // If midnight. 
+3

一般的に、これは非常に悪い考えです。なぜなら、構造体にパディングがあるとすぐに予測できない方法で失敗する可能性があるからです。あなたが何をしているのかを知っておらず、危険を認識していない限り、私は本当にこれを覚えていません。 – unwind

+1

@unwindはい、パディングは、ユーザーがそれを知らないと問題を引き起こす可能性があります。さらに、ユーザーがパディングを含む構造体サイズを指定したとしても、パディング内のガーベッジ値によって、これが異なる振る舞いをする可能性があります。 – Mazhar

+1

@unwindこれは古典的なUnixプログラミングの習慣です。しかし、一旦割り当てられた構造体に対して 'memset'や' bzero'を行うことによって、パディングが0に正しく初期化されることを確認することは、古典的なUnixプログラミングの習慣です。古典的なUnixソケットライブラリのいくつかは、まさにそのように機能します。 – tofro

3

を比較します。

最も良い方法は、指定された型の2つの構造体オブジェクトを比較するカスタム比較関数を書くことです。最初の構造体が2番目の構造体よりも小さい、等しい、または大きいと考えられる場合は、ゼロより小さい整数、ゼロより大きい値またはゼロより大きい整数を返す関数の形で行うことをお勧めします。

は次の形式を使用します。

int compare_date (const void* obj1, const void* obj2) 
{ 
    const date* d1 = obj1; 
    const date* d2 = obj2; 
    int diff; 

    diff = d1->year - d2->year; 
    if(diff != 0) 
    return diff; 

    diff = d1->month - d2->month; 
    if(diff != 0) 
    return diff; 

    diff = d1->day - d2->day; 
    return diff; 
} 

をこの形式の利点は、あなたが今、標準ライブラリ関数bsearchと一緒にこの機能を使用qsort、同様のことができるということです。これらの関数はvoidポインターの理由です。これはCで比較関数を書くための汎用の型に依存しない方法です(時にはこれらを「ファンクター」と呼びます)。

+0

なぜあなたはconst date *として指定したobj1とobj2を使用していないのですか? – Mazhar

+1

ええと、それでも、私は1位に比較型関数の型付きバージョンを作成し、その型なし型をラップしました。 'qsort()'と 'bsearch()'を使用しない場合のコンパイル時型チェックの利点を失うのはなぜですか? – alk

+2

@Mazharこれは一般的な形式なので、 'const void * 'を使うことによって、' bsearch'が望むような関数を使用します。基本的に、上記のフォームを使用することにより、無料で検索とソートのアルゴリズムが得られます。これは「ファンクタ」と呼ばれることもあります。 'bsearch'関数がどのように機能しているかを確認してください。 – Lundin

関連する問題