2012-03-06 8 views
0

У меня возникла проблема с включением файлов. Что я в основном сделал, это программа командной строки в C, которая работает с csv-файлом. Он имеет 5 команд: -menu, -add, -edit, -del, -verify. Все хорошо, за исключением -menu. Что должно произойти, когда я набираю «./passweb -menu» для визуального меню. Эта команда меню должна вызывать новую функцию, и ее необходимо разместить в отдельном файле c (aka menu.c).# включая файлы

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я не слишком уверен, как включить файлы для запуска в menu.c, потому что способ, которым я настроен прямо сейчас, passweb.c имеет все функции таких как -add и -edit и т. д. Я знаю, что вам нужно создавать файлы заголовков и т. д., но жалуется, что я дважды объявлял методы, что верно, поскольку я использую функции в файле меню.

Вот некоторые из кода:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "cipher.h" 
#include "menu.h" 
#include "passweb.h" 
#define MAXLENGTH 51 //longest length of a single record + 1 =51 bytes 
#define SIZEOFDB 1000 
#define ENCRYPT 5 

typedef struct rec 
{ 
    char name[MAXLENGTH]; 
    char pw[MAXLENGTH]; 
    char type[6]; 
    int boolean; 
}RECORD; 

int add(char *nName, char *nPw, char *nType, RECORD *arr, int size); 
void del (char *tName, RECORD *arr, int size); 
int edit(char *nName, char *nPw, char *nType, char *tName, char *tPw, RECORD *arr, int size); 
int verify (char *tName, char *tPw, RECORD *arr,int size); 

Это мой главный файл «passweb.c» и декларируется функции. Позже, в основном, я вызову функцию меню, которая находится в файле menu.c. В функции меню я использую «add», «edit», «del» и т. Д., Которые я написал в этом .c файле. Как вы можете видеть сверху, я включил файлы заголовков.

Что делать, чтобы решить эту проблему? Извините за длинный пост.

Thanks

+0

Какое ваше сообщение об ошибке? Что находится в файле заголовка с декларацией дубликатов? –

+0

'passweb.c: 20: ошибка: конфликтующие типы для 'add'' ' passweb.h: 12: error: предыдущая декларация' add 'была здесь Они подходят для каждой функции. Все в порядке, если я использую функцию, созданную, например, main.c, которая запускает функцию в menu.c, а затем menu.c запускает функцию, созданную main.c? –

+0

Хорошо, это лучше. Вы объявляете функцию дважды. Один раз в файле заголовка и один раз в C-файле. Вы можете только объявить что-то один раз для единицы перевода. –

ответ

1

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

Например, заголовок (test.h) будет иметь определения структуры и прототипы функций, таких как:

#ifndef TEST_H 
#define TEST_H 
struct myStruct { 
    int x; 
}; 

int Add(int lhs, int rhs); 
#endif 

и источник будет иметь:

#include "test.h" 
#include <stdio.h> 
int Add(int lhs, int rhs) 
{ 
    return lhs+rhs; 
} 
int main() 
{ 
    printf("%d",Add(2,3)); 
    return 0; 
} 
+0

Если я их в файле заголовка, значит ли это, что мне не нужны прототипы в файле c? –

+0

@YamatoC - если у вас есть то, что в заголовке, реализация? Если у вас есть реализация в заголовке, вам не нужно ничего, кроме 'include' в файле' .c'. – prelic

+0

Я имею в виду, что у меня есть прототипы в файле заголовка. Означает ли это, что мне не нужны прототипы в файле, в котором они реализованы? –

1

это в вашем файле заголовка и включают в себя это:

#ifndef FUNCS_H_ 
#define FUNCS_H_ 

int add(char *nName, char *nPw, char *nType, RECORD *arr, int size); 
void del (char *tName, RECORD *arr, int size); 
int edit(char *nName, char *nPw, char *nType, char *tName, char *tPw, RECORD *arr, int size); 
int verify (char *tName, char *tPw, RECORD *arr,int size); 

#endif /*FUNCS_H_*/ 

#ifdef защищает заголовок от мульти iple включение

1

Переместить декларацию add, del, edit и verify в новый заголовочный файл main.h

main.h Включите в основной файл .c и в menu.c

В целом также является хорошей идеей поместите директивы в файлы include, которые сообщают препроцессору, что они будут использовать их только один раз - Visual C++ имеет специальную директиву #pragma once, в противном случае вы можете использовать

#if ! __MENU_C 
#define __MENU_C 

. . . . 

#endif 
1

Файл заголовка должен содержать прототипы функций и необходимую информацию о типах данных, которые они ссылаются, например, определения вашей структуры. Он может также включает #define 'константы ed, встроенные функции, декларации переменных extern (которые будут объявлены обычно внутри одного из ваших .c файлов) и т. Д.

Как только у вас есть эти вещи в файле заголовка, вы можете удалить их из .c файла (ов); фактические определения функций с телами должны быть в файлах .c, но не дублируйте там прототипы. Затем вы заголовок #include в каждом файле .c, который нуждается в функциях и т. Д., Объявленных в нем.

Вы также должны убедиться, что элементы в файле заголовка не получают #include 'ed более одного раза в каждом исходном файле, даже косвенно (включая другие). Обычно охранники заголовка используется для этого, которые используют препроцессор условные, чтобы предотвратить обработку файла заголовка, когда он уже включен:

#ifndef SOMEHEADER_H 
# define SOMEHEADER_H 

/* header file contents */ 

#endif 

При компиляции, вы должны иметь возможность компилировать каждый .c файл отдельно, если вам нравится , или все вместе, если компилятор позволяет вам. При связывании вам нужно связать все объектные файлы. Для НКУ, делая как в одной команде, вы можете использовать что-то вроде этого:

gcc -o program_name first.c second.c third.c 

... который компилирует каждый .c файл в свой собственный файл .o, и связывает их все вместе при получении исполняемого файла.

Смежные вопросы