Выдает ошибку сборки компилятор

Рейтинг: -2Ответов: 1Опубликовано: 09.07.2023
alex-conquer@LAPTOP-EVM4AADF:/mnt/c/Users/USER/Desktop/prep_C$ make build
cc -Wpedantic -Wall -Wextra -Werror -I project/include -o ./main.out  project/src/main.c project/src/utils.c
/usr/bin/ld: /tmp/ccuH9ahV.o:(.bss+0x0): multiple definition of `client_data'; /tmp/ccZe8ERQ.o:(.bss+0x0): first defined here
/usr/bin/ld: /tmp/ccuH9ahV.o:(.bss+0x80): multiple definition of `transfer'; /tmp/ccZe8ERQ.o:(.bss+0x80): first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: main.out] Error 1

ФАЙЛ utils.h

#ifndef PROJECT_INCLUDE_UTILS_H_
#define PROJECT_INCLUDE_UTILS_H_
#include <stdio.h>

#define filename "transaction.dat"


typedef struct {
    int     Number;
    int     Client;
    char    Name[20];
    char    Surname[20];
    char    addres[30];
    char    TelNumber[15];
    double  indebtedness;
    double  credit_limit;
    double  cash_payments;
} Data;

Data client_data = {0};
Data transfer = {0};


void masterWrite(FILE *ofPTR, Data Client);
void transactionWrite(Data transfer);
void blackRecord(FILE *ofPTR, FILE *ofPTR_2, FILE *blackrecord, Data client_data, Data transfer);

#endif  // PROJECT_INCLUDE_UTILS_H_

Файл main.c

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int choice = 0;
    FILE *Ptr, *Ptr_2, *blackrecord;
    printf("%s", "please enter action\n1 enter data client:\n2 enter data transaction:\n3 update base\n");
    while (scanf("%d", &choice) != -1) {
        switch (choice) {
            case 1:
                Ptr = fopen("record.dat", "r+");
                if (Ptr == NULL) {
                    puts("Not acess");
                } else {
                    masterWrite(Ptr, client_data);
                    fclose(Ptr);
                }
                break;
            case 2:
                Ptr = fopen(filename, "r+");
                if (Ptr == NULL) {
                    puts("Not acess");
                } else {
                    transactionWrite(transfer);
                    fclose(Ptr);
                }
                break;
            case 3:
                Ptr = fopen("record.dat", "r");
                Ptr_2 = fopen("transaction.dat", "r");
                blackrecord = fopen("blackrecord.dat", "w");
                if (Ptr == NULL || Ptr_2 == NULL) {
                    puts("exit");
                } else {
                    blackRecord(Ptr, Ptr_2, blackrecord, client_data, transfer);
                    fclose(Ptr);
                    fclose(Ptr_2);
                    fclose(blackrecord);
                }
                break;
            default:
                puts("error");
                break;
}
        printf("%s", "please enter action\n1 enter data client:\n2 enter data transaction:\n3 update base\n");
    }
    return 0;
}   
 Файл  utils.c
void blackRecord(FILE *ofPTR, FILE *ofPTR_2, FILE *blackrecord, Data client_data, Data transfer) {
while (fscanf(ofPTR, "%15d%15s%15s%15s%15s%15lf%15lf%15lf", &client_data.Number, \
              client_data.Name, client_data.Surname, client_data.addres, client_data.TelNumber, \
              &client_data.indebtedness, &client_data.credit_limit, &client_data.cash_payments) != -1) {
while (fscanf(ofPTR_2, "%d %lf", &transfer.Number, &transfer.cash_payments) != -1) {
if (client_data.Number == transfer.Number && transfer.cash_payments != 0) {
client_data.credit_limit += transfer.cash_payments;
}
}
fprintf(blackrecord, "%-12d%-11s%-11s%-16s%20s%12.2f%12.2f%12.2f\n", client_data.Number, \
        client_data.Name, client_data.Surname, client_data.addres, client_data.TelNumber, \
        client_data.indebtedness, client_data.credit_limit, client_data.cash_payments);
rewind(ofPTR_2);
}
}

void masterWrite(FILE *ofPTR, Data Client) {
printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n\n",
"1 Number account: ",
"2 Client name: ",
"3 Surname: ",
"4 Addres client: ",
"5 Client Telnum: ",
"6 Client indebtedness: ",
"7 Client credit limit: ",
"8 Client cash payments: ");
while (scanf("%20d%20s%20s%20s%20s%20lf%20lf%20lf", &Client.Number, Client.Name, Client.Surname, \
    Client.addres, Client.TelNumber, &Client.indebtedness, &Client.credit_limit, \
&Client.cash_payments) != -1) {
fprintf(ofPTR, "%-12d%-11s%-11s%-16s%20s%12.2f%12.2f%12.2f\n", Client.Number, Client.Name, \
    Client.Surname, Client.addres, Client.TelNumber, Client.indebtedness, Client.credit_limit, \
Client.cash_payments);
printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n\n",
"1 Number account: ",
"2 Client name: ",
"3 Surname: ",
"4 Addres client: ",
"5 Client Telnum: ",
"6 Client indebtedness: ",
"7 Client credit limit: ",
"9 Client cash payments:");
}
}

void transactionWrite(Data transfer) {
printf("%s\n%s\n",
"1 Number account: ",
"2 Client cash payments: ");
while (scanf("%d %lf", &transfer.Number, &transfer.cash_payments) != -1) {
sscanf(filename, "%3d%lf\n", &transfer.Number, &transfer.cash_payments);
printf("%s\n%s\n",
"1 Number account:",
"2 Client cash payments: "
);
}
}

Ответы

▲ 1

При компиляции нескольких файлов переменные, объявленные в хеден файлах будут появляться постоянно с одним именем. И происходит ошибка объявления нескольких переменных с одним именем.
Если эти переменные должны быть в единственном числе, то их надо предварительно объявлять с приставкой extern.

utils.h :

extern Data client_data ;
extern Data transfer ;

И окончательно в каком-нибудь одном c-файле.

utils.c :

Data client_data = {0};
Data transfer = {0};