Программирование с использованием функций и структур на C, получение странного вывода без ошибок - PullRequest
4 голосов
/ 23 ноября 2010

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

//employee.h

int addEmployee(void);
int printEmployee(int i);

struct employeelist 
{
    char last [20];
    char first[20];
    int pnumber;
    int salary;
};


Файл "core" выполняет обе функции. Первая функция запрашивает количество сотрудников и возвращает значение для второй функции, где информация собирается и хранится. Там нет ошибок, и я проверил код несколько раз.

//employee.c

#include "employee.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int numE;
int i;

int addEmployee(void)
{
    struct employeelist employee[5]; 
    int numE; 


    printf("How many employees do you want to add to the list?: ");
    scanf("%d", &numE);
    printf("Please type in the last name, the first name,\nthe personal number and the salary of your employees.\n");

    for (i=0; i < numE; i++)
    {

    printf("Last name: ");
    scanf("%s", employee[i].last);  

    printf("First name: ");
    scanf("%s", employee[i].first);  

    printf("Personal number: ");
    scanf("%d", &employee[i].pnumber);  

    printf("Salary: ");
    scanf("%d", &employee[i].salary);  
    }

    return numE;
}

int printEmployee(int emp)
{
    struct employeelist employee[5]; 
    for (i=0; i < emp; i++)
    {

        printf("Last name: {%s}\nFirst name: {%s}\nPersonal number: {%d}\nSalary: {%d}\n",employee[i].last,employee[i].first, employee[i].pnumber, employee[i].salary);
    }

    getchar();
    getchar();
    return emp;
}


Последний файл содержит функцию main () для выполнения указанных выше функций.

#include "employee.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int emp;

int main ()
{
    struct employeelist employee[5]; 
    int emp = addEmployee();
    printEmployee(emp);
    return 0;
}


Теперь моя проблема в том, что все работает, только вывод неверен. Я даже не могу сказать, что это. Какая-то случайная смесь знаков, букв и цифр. Поскольку я понятия не имею, где моя ошибка, я был бы рад любому совету решить эту проблему. Спасибо. alt text


Я добавил скриншот своего вывода. Может быть, это поможет.

Ответы [ 6 ]

3 голосов
/ 23 ноября 2010

Вы пытаетесь использовать локальную переменную, которая перестает существовать, когда функция возвращает.

int addEmployee(void)
{
    struct employeelist employee[5];
    /* ... */
}

Переменная employee существует только внутри функции addEmployee (); и каждый раз, когда вызывается функция, это другой объект.

int printEmployee(int emp)
{
    struct employeelist employee[5];
    /* ... */
}

Этот employee не имеет отношения к тому, что есть в addEmployee.


Но не делай легкого сейчас (*); сделать правильную вещь : объявить массив в функции main () и передать его.

//employee.h

struct employeelist 
{
    char last [20];
    char first[20];
    int pnumber;
    int salary;
};

/* add up to `maxemp` employees to the array and
** return  number of employees added */
int addEmployee(struct employeelist *, int maxemp);

/* print all employees from index 0 to (nemp - 1) */
int printEmployee(struct employeelist *, int nemp);

Объявите массив в main () и передайте его

#include "employee.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main ()
{
    int emp;

    struct employeelist employee[5]; 
    int emp = addEmployee(employee, 5);
    printEmployee(employee, emp);
    return 0;
}

(*) Не объявлять глобальную переменную для сотрудников


Отредактировал employee.h и добавила функцию main ()

2 голосов
/ 24 ноября 2010

Суть проблемы в том, что вы работаете с тремя разными массивами сотрудников вместо одного массива, который, как вы думаете, у вас есть.Все, что объявлено внутри пары фигурных скобок в C, только «существует», пока программа выполняет код внутри этих фигурных скобок.Вы объявили три разных массива структур сотрудников в трех разных блоках кода.

Чтобы указать вам правильное направление (независимо от того, домашняя ли это работа или самостоятельная работа, это учебное упражнение, поэтому просто исправьтеваш код, вероятно, не тот, который вы хотите) вы должны подумать о том, как вы можете передать такой же массив сотрудников в каждую из ваших функций по очереди.(РЕДАКТИРОВАТЬ: pmg побеждает меня в этом.)

Объявите массив один раз, в вашей функции main (), как вы уже сделали, и измените две ваши функции printEmployee() и addEmployee(), чтобы получить этот массивв качестве параметра вместо объявления своих собственных локальных массивов.

Вот очень простой пример использования int, показывающий, как работают параметры и возвращаемые значения.Вам нужно немного почитать об указателях, чтобы распространить это на ваш случай.

int main() {
    int number = 2;
    int newNumber;
    newNumber = timesTwo(number);
    printf("number: %d newNumber: %d", number, newNumber);
}

int timesTwo(int param) {
    return param * 2;
}

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

2 голосов
/ 23 ноября 2010

В вашей функции печати есть новая переменная, которая даже не инициализирована. Таким образом, он содержит только мусор, и это напечатано

1 голос
/ 24 ноября 2010

Основная проблема, как уже говорили другие, заключается в том, что вы объявляете struct employeelist employee[5] в каждой из ваших функций. Это делает эти переменные локальными для их функций и, таким образом, недоступными из одной функции в другую. Поэтому, когда printEmployee отправляется на печать, данные, которые он печатает, являются бессмысленными.

Есть несколько вещей, которые необходимо исправить:

  • Сделайте одну декларацию вашего списка сотрудников в вашем основном (который у вас уже есть), а затем передайте это в функции. Вам нужно будет выполнить передачу с помощью имени массива, чтобы функции правильно обрабатывали массив.
  • В результате вышесказанного вам необходимо переместить объявление struct выше уровня прототипов функций, а затем изменить прототипы в employee.h, чтобы обеспечить передачу списка сотрудников.
  • Вам нужно будет убедиться, что пользователь не пытается ввести больше записей, чем для вашего массива. В качестве альтернативы, вы можете просто объявить указатель в основной и malloc () необходимую память в функции addEmployee.

Несколько других советов, чтобы немного облегчить себе жизнь:

  • Назовите вашу структуру employee (или что-то в этом роде) и ваш массив employeelist (или что-то подобное).
  • Используйте typedef в вашей структуре, чтобы сократить и упростить ваши объявления.
  • Измените вашего printEmployee на функцию void (то есть тип возврата void).
1 голос
/ 23 ноября 2010

Вы объявляете массив employee локально для обеих функций, чтобы они не могли получить доступ к данным друг друга.

0 голосов
/ 29 января 2013

Посмотрите .. Хорошо распределено и просто для чтения, просто нужно немного улучшить, чтобы стать больше и делать ту работу, которую вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...