roberthsu2003 / cAndC-

48 stars 18 forks source link

要求使用者輸入前幾名的學生 #45

Closed roberthsu2003 closed 3 months ago

roberthsu2003 commented 4 months ago

輸入

請輸入想要班上前幾名的學生:5

輸出

班上前5名的學生是:
xxxxx xx xx xx xxx
xxxxx xx xx xx xxx
xxxxx xx xx xx xxx
xxxxx xx xx xx xxx
xxxxx xx xx xx xxx

依據以下程式:

#include <iostream>
using namespace std;

typedef struct student {
  string name;
  int chinese;
  int english;
  int math;
} Student;

void random_student(Student s[], int elems) {
  int min = 50;
  int max = 100;
  for (int i = 0; i < elems; i++) {
    s[i].name = "第" + to_string(i + 1) + "號學生";
    s[i].chinese = random() % (max - min + 1) + min;
    s[i].english = random() % (max - min + 1) + min;
    s[i].math = random() % (max - min + 1) + min;
    cout << s[i].name << " ";
    cout << s[i].chinese << " ";
    cout << s[i].english << " ";
    cout << s[i].math << " ";
    cout << s[i].chinese + s[i].english + s[i].math << endl;
  }
}

int main() {
  srandom(time(NULL));
  int nums;
  cout << "請輸入學生數量:";
  cin >> nums;
  Student students[nums];
  random_student(students, nums);

}
fatpao commented 4 months ago

參考同學的,重新修改 不過還是無法理解同學student_info_t (星號)p_student_info,這個(星號)的做法

#include <iostream>
#include <iomanip>
//IO manipulation:控制輸出格式

using namespace std;

typedef struct student {
  string name;
  int chinese;
  int english;
  int math;
} Student;

void random_student(Student s[], int elems) {
  int min = 50;
  int max = 100;

  cout << setw(16) << "name"
       << setw(8)  << "chinese"
       << setw(8)  << "english"
       << setw(8)  << "math"
       << setw(8)  << "total"
       << endl;

  //setw(),設定列印時的欄位寬度,若為浮點數,小數點也佔一位。(設定後單次有效)
  //中英文不好對齊,改為全英文

  for (int i = 0; i < elems; i++) {
    s[i].name = "NO." + to_string(i + 1) + "-student";
    s[i].chinese = random() % (max - min + 1) + min;
    s[i].english = random() % (max - min + 1) + min;
    s[i].math    = random() % (max - min + 1) + min;
    cout << setw(16) << s[i].name
         << setw(8)  << s[i].chinese
         << setw(8)  << s[i].english
         << setw(8)  << s[i].math
         << setw(8)  << s[i].chinese + s[i].english + s[i].math
         << endl;
  }
}

void bobbles(Student s[], int elems){
  for (int i = 0; i < elems - 1; i++) {

    for (int j = i + 1; j < elems; j++) {

      if (s[i].chinese + s[i].english + s[i].math < s[j].chinese + s[j].english + s[j].math) {
        // 2數對調,大的往前
        Student temp = s[i];
        s[i] = s[j];
        s[j] = temp;              
      }
    }
  }
}

int main() {
  srandom(time(NULL));
  int nums;
  int rank;
  int i;

  cout << "請輸入學生數量:";
  cin >> nums;
  Student students[nums];
  random_student(students, nums);

  cout << "----------" << endl;
  cout << "請輸入要取到第幾名(總分由高到低):";
  cin >> rank;
  bobbles(students, nums);

  cout << setw(8) << "Rank"
       << setw(16) << "name"
       << setw(8)  << "chinese"
       << setw(8)  << "english"
       << setw(8)  << "math"
       << setw(8)  << "total"
       << endl;

  for (i = 0; i <= rank-1; i++){
  cout << "Rank" << setw(3) << to_string(i + 1) << ":"
       << setw(16) << students[i].name
       << setw(8)  << students[i].chinese
       << setw(8)  << students[i].english
       << setw(8)  << students[i].math
       << setw(8)  << students[i].chinese + students[i].english + students[i].math
       << endl;
  }
}

image

Norri2 commented 4 months ago

Last version of code has been updated at 6/23(Sun) 01:21

#include <iostream>
#include <iomanip>
using namespace std;

#define GET_RANDOM_NUMBER(MIN, MAX) \
        (random() % (MAX - MIN + 1) + MIN)

#define GET_TOTAL_SCORE(info) \
        (info.chinese + info.english + info.math)

typedef struct student_info_s
{
  string name;
  int chinese;
  int english;
  int math;  
} student_info_t; 

bool is_integer(const string *p_str)
{
  if(p_str == nullptr)
  {
    return false;
  }

  for (int i = 0; i < p_str->length(); i++)
  {
    if (! isdigit( p_str->c_str()[i] ) )
    {
      return false;
    }
  }

  return true;
}

void student_info_init(student_info_t *p_student_info, int elems)
{
  srandom(time(NULL));

  for (int i = 0; i < elems; i++)
  {
      p_student_info[i].name    = "Student no." + to_string(i + 1);
      p_student_info[i].chinese = GET_RANDOM_NUMBER(0, 100);
      p_student_info[i].english = GET_RANDOM_NUMBER(0, 100);
      p_student_info[i].math    = GET_RANDOM_NUMBER(0, 100);
  }
}

void output_student_info(student_info_t *p_student_info, int elems)
{
  cout << "-------------------------------------------------" << endl;
  cout << left  << setw(14) << "Name";
  cout << right << setw(8)  << "Chinese";
  cout << right << setw(8)  << "English";
  cout << right << setw(8)  << "Math";
  cout << right << setw(8)  << "Total" << endl;

  for (int i = 0; i < elems; i++)
  {    
    cout << left  << setw(14) << p_student_info[i].name;
    cout << right << setw(8)  << p_student_info[i].chinese;
    cout << right << setw(8)  << p_student_info[i].english;
    cout << right << setw(8)  << p_student_info[i].math;
    cout << right << setw(8)  << GET_TOTAL_SCORE(p_student_info[i]) << endl;
  }

  cout << "-------------------------------------------------" << endl;
}

void sort_by_total_score(student_info_t *p_student_info, int elems) 
{
  for (unsigned int i = 0; i < (elems - 1); i++) 
  {
    for (unsigned int j = (i + 1); j < elems; j++) 
    {
      if (GET_TOTAL_SCORE(p_student_info[i]) < 
          GET_TOTAL_SCORE(p_student_info[j])) 
      {
        student_info_t temp_info = p_student_info[i];
        p_student_info[i]        = p_student_info[j];
        p_student_info[j]        = temp_info;
      }
    } // j
  } // i
}

int main(void) 
{
  string user_input;
  int elem_of_student = 1;

  // Let the user input the number of students in his class
  while(1)
  {
    cout << "Typing in the number of students: ";
    cin >> user_input;

    if(! is_integer(&user_input))
    {
      cout << "\33[31m";
      cout << "[Error] Please type in an integer.";
      cout << "\33[0m";
      cout << endl << endl;

      continue;
    }

    // Transfer to integer
    elem_of_student = stoi(user_input);

    //If the number of top student is less than 1
    if(elem_of_student < 1)
    {
      cout << "\33[31m";
      cout << "[Error] The number of students must be greater than 0.";
      cout << "\33[0m";
      cout << endl << endl;
    }
    else
    {
      break;
    }
  }//while

  // Information of students creating
  student_info_t student_info[elem_of_student];

  student_info_init(student_info, elem_of_student);
  output_student_info(student_info, elem_of_student);
  cout << endl;

  // Sorting students by their total score
  sort_by_total_score(student_info, elem_of_student);

  // Let the user input the number of student total score rankings to be displayed
  int elem_to_display = 1;
  user_input.clear();

  while(1)
  {
    cout << "Typing in the number of student total score ranking " << endl
         << "of students to be displayed: ";
    cin >> user_input;

    //If the data typed in by user is not integer
    if(! is_integer(&user_input))  
    {
      cout << "\33[31m";
      cout << "[Error] Please type in an integer.";
      cout << "\33[0m";
      cout << endl << endl;

      continue;
    }

    // Transfer to integer
    elem_to_display = stoi(user_input);

    //If the number of top student is less than 1
    if(elem_to_display < 1)  
    {
      cout << "\33[31m";
      cout << "[Error] The number to display must be greater than 0.";
      cout << "\33[0m";
      cout << endl << endl;
    }

    //If the number of top student is greater than the number of students
    else if (elem_to_display > elem_of_student)  
    {
      cout << "\33[31m";
      cout << "[Error] The number to display must be less than" << endl
           << "or equal to the number of students.";
      cout << "\33[0m";
      cout << endl << endl;
    }
    else
    {
      break;
    }
  }//while

  output_student_info(student_info, elem_to_display);

  return 0;
}

image

以下是我對指標的理解,希望可以幫上忙:

當你新增了一個陣列: int arr[3] = {10, 20, 30}; 並假設這三個元素分別儲存在記憶體中的三個地方,位址分別是 0x0000、0x0004、0x0008。

arr這個名字本身,在一些場合中會被當成指標變數,它會指向陣列arr的第1個元素(0號)的記憶體位址。

當想要調用元素的記憶體位址時,有以下寫法:

arr       = 0x0000
(arr + 0) = 0x0000
&arr[0]   = 0x0000

(arr + 1) = 0x0004
&arr[1]   = 0x0004

當想要調用元素的內容時,有以下寫法:

*arr   = 10
arr[0] = 10

*(arr + 1) = 20
arr[1]     = 20

當你想要呼叫另一個函式func(),並且將arr的記憶體位址發送給它時, 你需要調用arr的記憶體位址,並寫到呼叫func()的括號裡:

func(arr);
func((arr + 0));
func(&arr[0]);

接著,函式會接收到arr的記憶體位址,你需要新增與arr同資料類型的指標 (這個例子為int), 並寫到函式本體的括號中,用來儲存你剛剛發送的arr的記憶體位址:

void func(int *arr)
void func(int arr[])

因此,Student s[] 就跟 Students *s 一樣意思,

進入函式func()後,可以直接使用前面的寫法來調用元素的記憶體位址或內容。

參考程式碼如下:

#include <iostream>

/* 使用 int arr[] 或 int *arr 來新增一個用來接收「呼叫時發送的arr的記憶體位址」的指標變數 */
void output_arr_to_console (int arr[], int elems)
{
    /* 使用 *(arr + i) 或  arr[i] 來調用陣列arr中,i號元素的內容 */
    /* 使用  (arr + i) 或 &arr[i] 來調用陣列arr中,i號元素所在的記憶體位址 */

    cout << "arr = { ";
    for(int i = 0 ; i < elems ; i++)
    {
        cout << *(arr + i) << " ";
    }
    cout << "}" << endl;

    cout << "address of arr = { ";
    for(int i = 0 ; i < elems ; i++)
    {
        cout << (arr + i) << " ";
    }
    cout << "}" << endl;
}

int main (void)
{
    int arr[] = {10, 20, 30};
    int elems_of_arr = sizeof(arr) / sizeof(arr[0]);

    /* 在呼叫函式時,使用 arr 或是 &arr[0] 來發送 arr[0] 的記憶體位址 */
    output_arr_to_console(arr, elems_of_arr);

    return 0;
}

執行結果: arr = { 10 20 30 } address of arr = { 0x0000 0x0004 0x0008 }

charlywang11 commented 4 months ago

要求使用者輸入前幾名的學生

#include <iostream>
#include <iomanip> //(參考同學的排版)

using namespace std;

typedef struct student {
  string name;
  int chinese;
  int english;
  int math;
  int result;
} Student;

void random_student(Student s[], int num) {
  int min = 50;
  int max = 100;
  for (int i = 0; i < num; i++) {
    s[i].name = "學生第" + to_string(i + 1) + "號";
    s[i].chinese = random() % (max - min + 1) + min;
    s[i].english = random() % (max - min + 1) + min;
    s[i].math = random() % (max - min + 1) + min;
    s[i].result = s[i].chinese + s[i].english + s[i].math;
  }
}

void print_students(Student s[], int num) {
  for (int i = 0; i < num; i++) {
    cout << setw(14) << s[i].name << "[ ";
    cout << setw(3) << s[i].chinese << " ";
    cout << setw(3) << s[i].english << " ";
    cout << setw(3) << s[i].math << " ";
    cout << setw(3) << "],總分為" << s[i].result << endl;
  }
}

void top_rank(Student s[], int num, int ranking) {
  for (int i = 0; i < num - 1; i++) {
    for (int j = i + 1; j < num; j++) {
      if (s[i].result < s[j].result) {
        Student temp = s[i];
        s[i] = s[j];
        s[j] = temp;
      }
    }
  }
}

int main() {
  srandom(time(NULL));
  int nums;
  int ranking;
  cout << "請輸入學生數量:";
  cin >> nums;
  Student(students[nums]);
  random_student(students, nums);
  print_students(students, nums);

  cout << "---------------------------------------" << endl;

  cout << "請輸入想知道總分前幾名的學生(1~" << nums << "):";
  cin >> ranking;
  top_rank(students, nums, ranking);
  cout << "總分前" << ranking << "名的學生是(依序):" << endl;
  print_students(students, ranking);

  return 0;
}

image

createcube commented 4 months ago
#include <iostream>
using namespace std;

typedef struct student {
  string name;
  int chinese;
  int english;
  int math;
  int sum;
} Student;

void random_student(Student s[], int elems) {
  int min = 0;
  int max = 100;
  for (int i = 0; i < elems; i++) {
    s[i].name = "第" + to_string(i + 1) + "號學生";
    s[i].chinese = random() % (max - min + 1) + min;
    s[i].english = random() % (max - min + 1) + min;
    s[i].math = random() % (max - min + 1) + min;
    s[i].sum = s[i].chinese + s[i].english + s[i].math;
    cout << s[i].name << " ";
    cout << s[i].chinese << " ";
    cout << s[i].english << " ";
    cout << s[i].math << " ";
    cout << s[i].sum << endl;
  }
}

void sort(student a[], int n){
  for (int i = 0; i < n - 1; i++) {
    for (int j = i + 1; j < n; j++) {
      if (a[i].sum < a[j].sum) {
        Student temp;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;

      }
    }
  }
}

void top(Student students[], int nums, int ranking){
  for(int i =0; i<nums; i++){
    cout << "第" << i+1 << "名是";
    cout << students[i].name << " ";
    cout << students[i].chinese << " ";
    cout << students[i].english << " ";
    cout << students[i].math << " ";
    cout << students[i].sum << endl;
  if(students[i].sum == students[i+1].sum){
    cout << "第" << i+1 << "名是";
    cout << students[i+1].name << " ";
    cout << students[i+1].chinese << " ";
    cout << students[i+1].english << " ";
    cout << students[i+1].math << " ";
    cout << students[i+1].sum << endl;
    i += 1;
  }
  if(i+1 == ranking){
    break;
    }
  }
}

int main() {
  srandom(time(NULL));
  int nums;
  cout << "請輸入學生數量:";
  cin >> nums;
  Student students[nums];
  random_student(students, nums);

  int ranking;
  cout << endl;
  cout << "請輸入想要前幾名的學生:";
  cin >> ranking;
  cout << endl;
  sort(students, nums);
  top(students, nums, ranking);

return 0;
}