我正在撰寫自己的 cat 實作并getopt_long用于決議命令列引數。我有三個檔案:一個是函式頭檔案,一個是函式定義檔案,一個是 main.c 檔案。
這是頭檔案:
#ifndef MY_CAT_FUNCS_H_
#define MY_CAT_FUNCS_H_
#include <stddef.h>
#include <getopt.h>
const char* short_options = "benst";
const struct option long_options[] = {
{"number-nonblank", no_argument, NULL, 'b'},
{"number", no_argument, NULL, 'n'},
{"squeeze-blank", no_argument, NULL, 's'},
{NULL, 0, NULL, 0}
};
int get_flags(const char* short_options, const struct option long_options[], int argc, char **argv, int* flag_b, int* flag_e, int* flag_n, int* flag_s, int* flag_t);
void flags_controller(int optind, int argc, char** argv, int flag_b, int flag_e, int flag_n, int flag_s, int flag_t);
void output(char *filename);
void flag_n_app(char *filename);
#endif // MY_CAT_FUNCS_H_
這是源檔案:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "my_cat_funcs.h"
int get_flags(const char* short_options, const struct option long_options[], int argc, char **argv, int* flag_b, int* flag_e, int* flag_n, int* flag_s, int* flag_t) {
int option_index;
int res;
while ((res = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) {
switch (res) {
case 'b': {
printf("It was flag --number-nonblank\n");
*flag_b = 1;
break;
}
case 'n': {
*flag_n = 1;
break;
}
case 's': {
printf("It was flag squeeze-blank\n");
*flag_s = 1;
break;
}
case 'e': {
printf("It was flag e\n");
*flag_e = 1;
break;
}
case 't': {
printf("It was flag t\n");
*flag_t = 1;
break;
}
case '?': default: {
printf("found unknown option");
break;
}
}
}
return optind;
}
void flags_controller(int optind, int argc, char** argv, int flag_b, int flag_e, int flag_n, int flag_s, int flag_t) {
while (optind < argc) {
if (flag_b flag_e flag_n flag_s flag_t == 0) {
output(argv[optind]);
} else {
if (flag_n) {
flag_n_app(argv[optind]);
output("buffer.txt");
}
}
optind ;
}
}
void flag_n_app(char *filename) {
char *line_buf = NULL;
size_t line_buf_size = 0;
int line_count = 0;
ssize_t line_size;
FILE *fp = fopen(filename, "r");
FILE *fbuf = fopen("buffer.txt", "w ");
if (fp) {
line_size = getline(&line_buf, &line_buf_size, fp);
while (line_size >= 0) {
line_count ;
fprintf(fbuf, "m\t", line_count);
ssize_t i = 0;
while(i < line_size) {
putc(line_buf[i ], fbuf);
}
line_size = getline(&line_buf, &line_buf_size, fp);
}
free(line_buf);
line_buf = NULL;
fclose(fp);
fclose(fbuf);
} else {
fprintf(stderr, "Error opening file '%s'\n", filename);
}
}
void output(char *filename) {
char *line_buf = NULL;
size_t line_buf_size = 0;
int line_count = 0;
ssize_t line_size; //ssize_t able to represent -1 for errors
FILE *fp = fopen(filename, "r");
if (fp) {
line_size = getline(&line_buf, &line_buf_size, fp);
while (line_size >= 0) {
line_count ;
ssize_t i = 0;
while(i < line_size) {
putc(line_buf[i ], stdout);
}
line_size = getline(&line_buf, &line_buf_size, fp);
}
free(line_buf);
line_buf = NULL;
fclose(fp);
} else {
fprintf(stderr, "Error opening file '%s'\n", filename);
}
}
這是主檔案:
#define _GNU_SOURCE
#include "my_cat_funcs.h"
int main(int argc, char **argv) {
int flag_b, flag_e, flag_n, flag_s, flag_t;
int optind = get_flags(short_options, long_options, argc, argv, &flag_b, &flag_e, &flag_n, &flag_s, &flag_t);
flags_controller(optind, argc, argv, flag_b, flag_e, flag_n, flag_s, flag_t);
return 0;
}
我以為我正確地包含了所有內容,但是我有這個錯誤:
gcc -Wall -Wextra -Werror my_cat.c my_cat_funcs.c -o my_cat
/usr/bin/ld: /tmp/ccqYSlAb.o:(.data.rel.local 0x0): multiple definition of `short_options'; /tmp/cczSyKQa.o:(.data.rel.local 0x0): first defined here
/usr/bin/ld: /tmp/ccqYSlAb.o:(.data.rel.ro.local 0x0): multiple definition of `long_options'; /tmp/cczSyKQa.o:(.data.rel.ro.local 0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: my_cat] Error 1
我不明白為什么會這樣。畢竟頭檔案中還是有函式頭的。但對他們來說,沒有錯誤。多重定義僅適用于具有短標志的字串和具有長標志的結構。我不明白如何從這個錯誤文本中理解第一個定義的確切位置。你能告訴我為什么會這樣嗎?我該如何解決?
uj5u.com熱心網友回復:
您的頭檔案包含short_options和的定義long_options。因此,當您的每個 .c 檔案都包含它時,它們都定義了這些變數,然后當您隨后鏈接它們時,您就有了多個定義。
這些根本不應該在標題中,因為它們沒有在第一個源檔案中使用。相反,將它們放在您的主檔案中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/534153.html
