2016-04-22 12 views
5

私はC言語の初心者プログラマであり、問​​題はほとんどありません。私は2つの配列、学生名と学生ID番号の1つを作成し、それを並べ替えてさまざまな方法で印刷し、ID番号で配列を検索する基本的なプログラムを作成しています。ここでは、コードは次のようになります。配列をパラメータとして渡す際の問題

#include <stdio.h> 
#include <string.h> 
#define ARRAY_SIZE 3 
#define MAX_NAME_LENGTH 32 

int main() 
{ 
    // Student info arrays 
    char NAME[ARRAY_SIZE][MAX_NAME_LENGTH]; 
    int ID[ARRAY_SIZE]; 

    // Array for student IDs, shifted twice to the right 
    int shiftedID[ARRAY_SIZE]; 

    // Boolean value to keep while loop running and 
    // the ID search prompt repeating 
    int loop = 1; 

    // Counter variable for the for loop 
    int counter; 
    // Gets input values for the student info arrays 
    for (counter = 0; counter < ARRAY_SIZE; counter++) 
    { 
     printf("Input student name: "); 
     scanf("%s", NAME[counter]); 

     printf("Input student ID: "); 
     scanf("%d", &ID[counter]); 
    } 

    // Sorts the arrays 
    sort(NAME, ID); 

    // Prints the arrays 
    print_array(&NAME, ID); 

    // Shifts the ID value two bits to the right 
    shiftright(ID, shiftedID); 

    print_array(NAME, shiftedID); 

    // Repeatedely prompts the user for an ID to 
    // search for 
    while(loop == 1) 
    { 
     search_id(NAME, ID); 
    } 
} 

そしてここでは、関数の定義です:

#define ARRAY_SIZE 3 
#define MAX_NAME_LENGTH 32 
// Sorts the two arrays by student ID. (Bubble sort) 
void sort(char **nameArray, int idArray[]) 
{ 

    // Counter variables for the for loop 
    int firstCounter = 0; 
    int secondCounter = 0; 
    for(firstCounter = 0; firstCounter < ARRAY_SIZE; firstCounter++) 
    { 
     for(secondCounter = 0; secondCounter < ARRAY_SIZE - 1; 
       secondCounter++) 
     { 
      if(idArray[secondCounter] > idArray[secondCounter + 1]) 
      { 

       // Temporary variables for the sort algorithm 
       int tempInt = 0; 
       char tempName[32]; 

       tempInt = idArray[secondCounter + 1]; 
       idArray[secondCounter + 1] = idArray[secondCounter]; 
       idArray[secondCounter] = tempInt; 

       strcpy(tempName, nameArray[secondCounter + 1]); 
       strcpy(nameArray[secondCounter + 1], 
         nameArray[secondCounter]); 
       strcpy(nameArray[secondCounter], tempName); 
      } 
     } 
    } 
} 
// Searches the ID array for a user input student 
// ID and prints the corresponding student's info. 
void search_id(char **nameArray, int idArray[]) 
{ 
    // A boolean value representing whether or not 
    // the input ID value was found 
    int isFound = 0; 

    // The input ID the user is searching for 
    int searchID = 0; 

    printf("Input student ID to search for: "); 
    scanf("%d", &searchID); 

    // Counter variable for the for loop 
    int counter = 0; 
    while (counter < ARRAY_SIZE && isFound == 0) 
    { 
     counter++; 
     if (idArray[counter] == searchID) 
     { 
      // Prints the name associated with the input ID 
      isFound = 1; 
      printf("%s", nameArray[counter]); 
     } 
    } 

    // If the input ID is not found, prints a failure message. 
    if (isFound == 0) 
    { 
     printf("ID not found.\n"); 
    } 
} 

// Prints the name and ID of each student. 
void print_array(char **nameArray, int idArray[]) 
{ 
    // Counter variable for the for loop 
    int counter = 0; 

    printf("Student Name & Student ID: \n"); 
    for (counter = 0; counter < ARRAY_SIZE; counter++) 
    { 
     printf("%s --- %d\n", nameArray[counter], idArray[counter]); 
    } 
} 

// Shifts the ID value to the right by two bits 
void shiftright(int idArray[], int shiftedID[]) 
{ 
    // Counter variable for the for loop 
    int counter = 0; 
    for (counter = 0; counter < ARRAY_SIZE; counter++) 
    { 
     shiftedID[counter] = idArray[counter] >> 2; 
    } 
} 

私は、このプログラムは、より多くの私を取得するための運動ですかなり自然の中で基本的な、そして何よりもあることを承知しています

  1. 入力されたID番号が全くされている場合:よく私はいくつかの時間のためにそれに取り組んでいないされてきた、といくつかの問題を通じて取り組んできましたが、3つの問題に引っかかっているように見える、Cなどの言語に精通既に入力されている場合、セグメンテーションフォールトが発生します。 ID番号がすでに入力されている場合、ソート関数は決してifステートメントを通過せず、問題は発生しません。

  2. 名前/ IDの配列をprint_array関数に渡すと、IDはきれいに表示されますが、名前は完全に空白または一連の奇妙な文字として表示されます。

  3. プログラムの最後にIDで検索すると、最初に入力されたID番号(ID [0]の番号)はIDが見つからないというメッセージを表示します。うまく動作します - 第2号で述べたように、印刷すべき対応する名前を空白として印刷します。

ご迷惑をおかけして申し訳ございませんが、ご了承ください。私は本当に面白いだけでなく、非常に混乱し、脅迫的にそうであるように、Cで必要とされる細かな細部の背後にある力を見つけます。

+0

2D配列はダブルポインタ( 'char **')ではありません。 – BLUEPIXY

+0

渡す配列に一致するには、パラメータは 'char nameArray [ARRAY_SIZE] [MAX_NAME_LENGTH]'でなければなりません。あなたは 'ARRAY_SIZE'を省略することができます –

答えて

5

問題は、char [ARRAY_SIZE][MAX_NAME_LENGTH]char **は交換可能であると仮定されている

void sort(char **nameArray, int idArray[]) 

は配列へのポインタを使用するために

void sort(char nameArray[][MAX_NAME_LENGTH], int idArray[]) 

又は

void sort(char (*nameArray)[MAX_NAME_LENGTH], int idArray[]) 

でなければならないということですMAX_NAME_LENGTHcharあなたのsearch_id機能と同じです。

は、私はあなたのプログラムを再構築するためにあなたを助言するquestion 6.13 of C-FAQ

+1

これはすぐにすべての私の問題を解決しました。迅速な対応をありがとうございます。 – Geoiv04

2

に見てみましょう。むしろ、名前とIDのための2つの独立したアレイを記憶するよりも、あなたが必要なすべてのデータが含まれている構造体の配列で保存することができます:

typedef struct student 
{ 
    int id; 
    char name[MAX_NAME_LENGTH]; 
} student_t; 

student_t students[ARRAY_SIZE]; 

を今、あなたはせずにIDをソートすることによって、「不一致」になることはありません単一の配列を持っています名前など

あなたは、標準ライブラリ関数qsort()を使用してC言語で配列をソートすることができます。これは、あなたが非常に簡単ですコンパレータを定義する必要が

qsort(students, ARRAY_SIZE, sizeof(student_t), comparator); 

。一つの例は次のようになります。

int comparator(const void *lhs, const void *rhs) 
{ 
    const student_t *s1 = lhs, *s2 = rhs; 
    return s1->id - s2->id; 
} 

それがソートされた後、あなたが学生の配列を検索するために、別の標準ライブラリ関数bsearch()と同じコンパレータを使用することができます。

student_t key = { 42 }; // name doesn't matter, search by ID 
student_t* result = bsearch(&key, students, ARRAY_SIZE, sizeof(student_t), comparator); 

これらの標準関数が何よりも効率的であなたは間違いの可能性が少なく、コードをはるかに少なく書かなければなりませんでした。

+0

これはプログラムを書くより効率的な方法のようですので、私は将来このようなものを使うでしょう。いずれにしても優秀な答え。 – Geoiv04

関連する問題