2012-05-13 11 views
-1

私はこのコードを持っています。メイン関数から2回sportPrisevinners関数を呼び出すと、この関数の最初の呼び出しであれば正しく動作し、正しい結果を返すが、2回目に呼び出すと同じ引数でこの関数を渡しても正しくない結果が返される。この問題を解決するのを手伝ってください。C++関数が2回呼び出すことができません

const char* countries[] = {"ru", "gb", "us", "uk", "ch", "de"}; 
const int countriesCount = 6; 
const char* sports[] = {"runing", "swiming", "baseball", "football", "jumping", "kerling"}; 
const int sportsCount = 6; 

enum { 
    Empty = 0, 
    Bronse, 
    Silver, 
    Gold 
}; 

struct member { 
    char sport[9]; 
    char country[3]; 
    int points; 
    int medal; 
}; 

struct members { 
    member* list; 
    int count; 
}; 

string medalToStr(int medal) 
{ 
    switch (medal) { 
    case Gold: 
     return "Gold"; 
    case Silver: 
     return "Silver"; 
    case Bronse: 
     return "Bronse"; 
    default: 
     return "Empty"; 
    } 
} 

void printMembers(members &list) 
{ 
    for (int i = 0; i < list.count ; i++) 
     cout << /*i << " " <<*/ medalToStr(list.list[i].medal) << " in " 
      << list.list[i].sport << " with " << list.list[i].points 
      << " from " << list.list[i].country << endl; 
} 

void generate() 
{ 
    ofstream file("members.dat", ios::binary|ios::trunc); 

    member temp; 

    for (int i = 0; i < sportsCount ; i++) 
     for (int j = 0; j < countriesCount ; j++) 
     { 
      int count = rand()%5+5; 
      for (int k = 0; k < count ; k++) 
      { 
       strcpy(&temp.sport[0], sports[i]); 
       strcpy(&temp.country[0], countries[j]); 
       temp.points = rand()%100; 
       temp.medal = Empty; 

       file.write((char*)&temp, sizeof(member)); 
      } 
     } 

    file.close(); 
} 

members sportPrisevinners(const char* sport) 
{ 
    //reading 
    ifstream file("members.dat", ios::binary); 
    member* loaded = new member[60]; 
    int pos = 0; 
    while (!file.eof()) 
    { 
     member temp; 

     file.read((char*)&temp, sizeof(member)); 

     static bool reading = false; 
     if (strncmp(&temp.sport[0], sport, strlen(sport))==0) { 
      reading = true; 
      loaded[pos++] = temp; 
     } else if (reading) { 
      break; 
     } 
    } 
    file.close(); 

    //sorting 
    int count = 3; 
    for (int i = 0; i < pos-1 ; i++) 
    { 
     for (int j = i+1; j < pos ; j++) 
      if (loaded[i].points<loaded[j].points) 
      { 
       member temp = loaded[i]; 
       loaded[i] = loaded[j]; 
       loaded[j] = temp; 
      } 

     if (i<count) { 
      static int last = -1; 

      if (loaded[i].points==last) 
       count++; 

      loaded[i].medal = count-i; 
      last = loaded[i].points; 
     } else break; 
    } 

    //returning 
    members result; 

    result.list = new member[count]; 
    memcpy(result.list, loaded, count*sizeof(member)); 
    /*for (int i = 0; i < count; i++) 
     result.list[i] = loaded[i];*/ 
    result.count = count; 

    delete[] loaded; 

    return result; 
} 

int main(int /*argc*/, char */*argv*/[]) 
{ 
    srand(time(0)); 

    generate(); 

    members r = sportPrisevinners(sports[4]); 
    printMembers(r); 
    delete[] r.list; 
    members l = sportPrisevinners(sports[5]); 
    printMembers(l); 
    delete[] l.list; 

    system("pause"); 

    return 0; 
} 
+2

valgrindのようなもので実行してみてください - あなたが未定義の動作をしているように見えます。 – Flexo

+0

私はまた、最小のテストケース(1人または2人のメンバー)を作ろうとします。そうすれば、予想される出力が何であるべきか、そして実際の出力が何であるかのように、より多くの情報をここに与えることができます。コード内で、操作が1つずつ削除されることで問題が発生する箇所を絞り込んでください。 – LiMuBei

+0

あなたのプログラムで 'std :: vector'を使わないのはなぜですか?それははるかに適切かつ簡単になります。 C++で記述するときは、直接メモリ操作を避ける必要があります。 –

答えて

3

私はそれがあなたの関数内の静的なローカル変数だと思います。関数呼び出しのたびに同じ値を持たず、結果に影響を与える可能性があります。これらの変数の初期化は、初めてスコープに入ったときに1度だけ実行されます。そのため、関数が呼び出されるたびに、関数が最後に実行したときの値を取得します。

関連する問題