2016-04-22 4 views
5

Я начинающий программист в C, и я сталкиваюсь с проблемой, которая почти болезненно проста. Я пишу базовую программу, которая создает два массива, одно из имен учеников и один из идентификационных номеров учеников, затем сортирует их и печатает их различными способами и, наконец, позволяет пользователю выполнять поиск массивов по идентификационному номеру. Вот код:Проблемы с проходящими массивами как параметры

#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; 
    } 
} 

Я знаю, что эта программа является довольно простой по своей природе, и больше всего это упражнение, чтобы получить меня больше хорошо разбирается в таких языках, как C, я работал на нем в течение некоторого времени, и работали через несколько проблем, но, похоже, не застревать на трех вопросах:

  1. Если номера ввода идентификаторов нет t ввод уже по порядку, возникает ошибка сегментации. Если идентификационные номера вводятся уже по порядку, функция сортировки никогда не проходит через оператор if, и никаких проблем не возникает.

  2. При передаче массивов имен/идентификаторов функции print_array идентификаторы печатаются очень хорошо, но имена будут напечатаны либо полностью пустыми, либо сериями странных символов.

  3. При поиске по идентификатору в конце программы номер идентификатора, который был введен первым (так, номер в ID [0]) отображает сообщение, не найденное ID, где все номера с индексом 1 или выше будут работайте отлично - помимо названий, которые должны быть напечатаны, печатаются как пустые, как указано во втором выпуске.

Любой совет, который я могу получить, был бы очень благодарен! Я нахожу, что сила, стоящая за прекрасными деталями, необходимыми в 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 s, то же самое для вашей функции search_id.

Посмотрите question 6.13 of C-FAQ

+1

Это быстро решило все мои проблемы. Спасибо за быстрый ответ. – Geoiv04

2

Я бы посоветовал вам перестроить свою программу. Вместо того, чтобы хранить два независимых массива имен и идентификаторов, вы можете хранить один массив структур, которые содержат все необходимые данные:

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

student_t students[ARRAY_SIZE]; 

Теперь у вас есть один массив, который никогда не может стать «несовпадающими» путем сортировки идентификаторов без имена и т. д.

Вы можете отсортировать массив в C с использованием стандартной функции библиотеки qsort():

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