这是我的C代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define TEAMNB 16
#define PM 4
/**
* Team struct
*/
typedef struct team{
char name[20]; /**< The team's name */
int noteWin; /**< Points won by this team */
int noteLost; /**< Points lost by this team */
}Team;
#define SHM_SIZE 16*sizeof(Team)
char* getName(Team team);
int getNoteWin(Team team);
int getNoteLost(Team team);
Team getIElem(Team* teamList, int i);
void traverse(Team* teamList, int size);
void getTeamsName(int size, char (*arr)[16], char filePath[30]);
void match(int t1, int t2, int pm, Team* teamList,int tour);
int findT1(Team* teamList, int start, int end, int tour);
int findT2(Team* teamList, int start, int end, int tour);
int mutexId;
static struct sembuf sP ={0,-1,0};
static struct sembuf sV = {0, 1,0};
void P(int mutexId);
void V(int mutexId);
int main(int argc, char *argv[]){
if(argc < 3){
exit(0);
}
printf("main进程的pid = %d",getpid());
int size = atoi(argv[1]);
char nbE[size][16];
getTeamsName(size,nbE ,argv[2]);
int shmid;
Team *teamList;
// Create the shared memory segment with read and write permissions for all users
key_t key = ftok(".", 1);
if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) < 0) {
perror("shmget");
exit(1);
}
// Attach the shared memory segment to our data space
if ((teamList = shmat(shmid, NULL, 0)) == (Team *) -1) {
perror("shmat");
exit(1);
}
// Application of mutex
key_t key2 = ftok(".",0);
mutexId = semget(key2,1,IPC_CREAT|IPC_EXCL|0600);
semctl(mutexId,0,SETVAL,1);
// Initialization the array of Team types
for (int i = 0; i < TEAMNB; i++) {
strcpy(teamList[i].name, nbE[i]);
teamList[i].noteWin = 0;
teamList[i].noteLost = 0;
}
pid_t pid;
int span;
// tour
for(int i = 1; i <= log(TEAMNB)/log(2.0); i++){
span = pow(2,i) ;
int j;
for(j = 0; j < TEAMNB; j=j+span){
int t1 = findT1(teamList, j, j+span-1,i-1);
int t2 = findT2(teamList, j, j+span-1,i-1);
switch(pid = fork()){
case -1:
perror("fork");
exit(-1);
case 0:
match(t1,t2,PM,teamList,i);
exit(0);
}
}
for(int k = 0; k < j;k++){
wait(NULL);
}
}
traverse(teamList,16);
// Removing a mutex
semctl(mutexId,0,IPC_RMID,0);
// Detach the shared memory segment
if (shmdt(teamList) == -1) {
perror("shmdt");
exit(1);
}
return 0;
}
/****************************************************************************/
/**The specific implementation of the function declared in the file header**/
/****************************************************************************/
/**
* @fn getName
* @brief Get the name of the team.
* @param team The team you specify.
* @return The name of the team.
*/
char* getName(Team team){
return team.name;
}
/**
* @fn getNoteWin
* @brief Get the NoteWin of the team.
* @param team The team you specify.
* @return The NoteWin of the team.
*/
int getNoteWin(Team team){
return team.noteWin;
}
/**
* @fn getNoteLost
* @brief Get the NoteLost of the team.
* @param team The team you specify.
* @return The NoteLost of the team.
*/
int getNoteLost(Team team){
return team.noteLost;
}
/**
* @fn getIElem
* @brief Get the i-th team.
* @param teamList An array of Team types.
* @param i The index you specify.
* @return The team you want.
*/
Team getIElem(Team* teamList, int i){
return teamList[i];
};
/**
* @fn findT1
* @brief In the [start] to [end] subscript of the teamlist, find the first team that has played a [tour] round and won all of its matches..
* @param teamList An array of Team types.
* @param start The start index.
* @param end The end index.
* @param tour Number of rounds of the competition.
* @return The index of the first team you want.
*/
int findT1(Team* teamList, int start, int end, int tour){
for(int i = start; i <= end; i++){
if(teamList[i].noteWin == tour){
return i;
}
}
return -1;
}
/**
* @fn findT2
* @brief In the [start] to [end] subscript of the teamlist, find the second team that has played a [tour] round and won all of its matches.
* @param teamList An array of Team types.
* @param start The start index.
* @param end The end index.
* @param tour Number of rounds of the competition.
* @return The index of the second team you want.
*/
int findT2(Team* teamList, int start, int end, int tour){
for(int i = end; i >= start; i--){
if(teamList[i].noteWin == tour){
return i;
}
}
return -1;
}
/**
* @fn traverse
* @brief Traverse the array.
* @param teamList An array of Team types.
* @param i The size of the array.
*/
void traverse(Team* teamList, int size){
for(int i = 0; i < size; i++){
Team team = getIElem(teamList, i);
printf("team : %s\t\t noteWin = %d\t noteLost = %d\n",getName(team), getNoteWin(team), getNoteLost(team));
}
}
/**
* @fn getTeamsName
* @brief Get a array of char* types.
* @details The return array is passed into the function and taken as the second argument
* @param size Total number of teams.
* @param arr An empty array of char* to hold the results.
* @param filepath The txt file from which the information needs to be extracted
*/
void getTeamsName(int size, char (*arr)[16], char filePath[30]){
FILE *f = fopen(filePath,"r");
int i,j;
for(i = 0; i < size; i++){
fscanf(f, "#%[^#]#\n", arr[i]);
}
fclose(f);
}
/**
* @fn P
* @brief block on a mutex
* @param mutexId the id of the mutex.
*/
void P(int mutexId){
semop(mutexId,&sP,1);
}
/**
* @fn V
* @brief unblock a mutex
* @param mutexId the id of the mutex.
*/
void V(int mutexId) {
semop(mutexId,&sV,1);
}
/**
* @fn match
* @brief Simulation of two teams playing a match.
* @param t1 The index of the first team.
* @param t2 The index of the second team.
* @param pm Race point setting.
* @param teamList An array of Team types.
* @param tour Number of rounds of the competition.
*/
void match(int t1, int t2, int pm, Team* teamList,int tour){
srand(time(NULL));
// Initialize the actions of the attacker and the defender
char* offensive[20] = {"essayer","botter"};
char* defense[20] = {"tacler","Gatekept","GateKeepFail"};
// sign = 0 : teamList[t1] is the attacking team
// sign = 1 : teamList[t2] is the attacking team
int signe = rand() % 2, offensiveIndex, defenseIndex;
// Initialize the scores of both teams
int potinT1=0,potinT2=0;
// Initialize the name of the output txt file
char* filePath = (char*)malloc(strlen(getName(getIElem(teamList,t1))) + strlen(getName(getIElem(teamList,t2))) + 10);
sprintf(filePath, "%s_VS_%s.txt",getName(getIElem(teamList,t1)),getName(getIElem(teamList,t2)));
FILE *f = fopen(filePath,"a");
printf("\033[43;31m%d tour\033[0m\n",tour);
printf("\033[43;31m%-15s : %-12s\t<====>\t%-15s : %-12s\t%s => %d : %d\033[0m\n","EquipeOffensive","OffenAction","EquipeDenfense","DefenAction","_NOTE_",0,0);
fprintf(f,"%d tour\n",tour+1);
fprintf(f,"%-15s : %-12s\t<====>\t%-15s : %-12s\t%s => %d : %d\n","EquipeOffensive","OffAction","EquipeDenfense","DefenAction","_NOTE_",0,0);
// Loop until one of the teams gets a match point
while(potinT1 < pm && potinT2 < pm){
offensiveIndex = rand() % 2;
defenseIndex = rand() % 3;
char* offensiveAction = offensive[offensiveIndex];
char* defenseAction = defense[defenseIndex];
if(strcmp(defenseAction, "tacler")==0 || strcmp(defenseAction, "GateKeepFail")==0){
if(strcmp(defenseAction, "GateKeepFail") == 0){
if(signe == 0){
++potinT1;
printf("\n%s a gagné un point!\n",getName(getIElem(teamList,t1)));
fprintf(f,"\n%s a gagné un point!\n",getName(getIElem(teamList,t1)));
}
else{
++potinT2;
printf("\n%s a gagné un point!\n",getName(getIElem(teamList,t2)));
fprintf(f,"%s a gagné un point!\n\n",getName(getIElem(teamList,t2)));
}
}
}
if(signe == 0){
printf("%-15s : %-12s\t<====>\t%-15s : %-12s\t%s => %d : %d\n",getName(getIElem(teamList,t1)), offensiveAction, getName(getIElem(teamList,t2)),defenseAction,"_NOTE_",potinT1,potinT2);
fprintf(f,"%-15s : %-12s\t<====>\t%-15s : %-12s\t%s => %d : %d\n",getName(getIElem(teamList,t1)), offensiveAction, getName(getIElem(teamList,t2)),defenseAction,"_NOTE_",potinT1,potinT2);
}
else{
printf("%-15s : %-12s\t<====>\t%-15s : %-12s\t%s => %d : %d\n",getName(getIElem(teamList,t2)), offensiveAction, getName(getIElem(teamList,t1)),defenseAction,"_NOTE_",potinT2,potinT1);
fprintf(f,"%-15s : %-12s\t<====>\t%-15s : %-12s\t%s => %d : %d\n",getName(getIElem(teamList,t2)), offensiveAction, getName(getIElem(teamList,t1)),defenseAction,"_NOTE_",potinT2,potinT1);
}
signe = rand() % 2;
usleep(1000000);
}
P(mutexId);
if(potinT1 == pm){
int noteWin = teamList[t1].noteWin;
teamList[t1].noteWin = noteWin + 1;
int noteLost = teamList[t2].noteLost;
teamList[t2].noteLost = noteLost + 1;
printf("%s gagne %d point\n", getName(getIElem(teamList,t1)),getNoteWin(getIElem(teamList,t1)));
fprintf(f,"gagnant : %-15s\trate : %-15s\n",getName(getIElem(teamList,t1)),getName(getIElem(teamList,t2)));
}
else{
int noteWin = teamList[t2].noteWin;
teamList[t2].noteWin = noteWin + 1;
int noteLost = teamList[t1].noteLost;
teamList[t1].noteLost = noteLost + 1;
printf("%s gagne %d point\n", getName(getIElem(teamList,t2)),getNoteWin(getIElem(teamList,t2)));
fprintf(f,"gagnant : %-15s\trate : %-15s\n",getName(getIElem(teamList,t2)),getName(getIElem(teamList,t1)));
}
V(mutexId);
fclose(f);
f = NULL;
free(filePath);
filePath = NULL;
}
我是用Mac的,当我用doxygen命令行解析输出html后,打开index.html一片空白,只有结构体的解析,有碰到这种问题的人吗?可能是config_file_name文件什么参数调错了吗?
参考GPT和自己的思路:
首先,您需要检查一下是否正确安装了Doxygen和是否已正确配置配置文件。如果您使用的是默认配置文件,则应该没有问题。
在您的问题描述中,并没有提供Doxygen命令行的完整内容和正确的配置文件。因此,我们无法确切地知道问题在哪里。但是,请注意以下几点:
您的代码中有一些注释使用了“/**<”和“*/”,这在Doxygen中是不正确的。正确的注释格式应该是“/*”和“/”。
您使用的是相对路径“.”创建共享内存,这可能会导致无法正确访问共享内存。请使用绝对路径来确保无误。
在您的代码中可能包含一些不受支持的语法,例如“#define PM 4”,这可能会导致Doxygen无法解析代码。建议在代码中省略宏定义等不必要的语法。
最后,请确保您使用的Doxygen版本是最新的,并按照官方文档和教程正确配置和运行Doxygen。
参考GPT和自己的思路:
首先,你需要检查你的Doxygen配置文件是否配置正确。你可以检查以下几个参数:
如果这些参数设置正确,那么你可以检查一下代码是否有语法错误。如果有语法错误,Doxygen可能无法解析代码。
最后,你可以尝试删除Doxygen生成的文件,然后再重新生成一遍。有时候,生成过程会出现错误,导致文件无法正确打开。
参考GPT和自己的思路,根据你提供的代码,并没有语法错误或逻辑错误。以下是一些可能导致此问题的原因和解决方案:
1.检查 Doxygen 配置文件:可能是您的 Doxygen 配置文件没有正确设置,导致 Doxygen 没有正确解析您的代码并生成文档。请确保您的配置文件正确设置了输入和输出文件夹,以及其他必要的选项。
2.检查源代码:可能是您的源代码中缺少必要的注释,导致 Doxygen 无法生成文档。请确保您的源代码中包含适当的注释,以便 Doxygen 可以正确解析并生成文档。
3.检查 Doxygen 版本:可能是您使用的 Doxygen 版本与您的代码不兼容,导致 Doxygen 无法正确解析并生成文档。请确保您使用的是最新版本的 Doxygen,并检查其与您的代码的兼容性。
4.检查 HTML 输出文件夹权限:可能是您的 HTML 输出文件夹没有正确的权限设置,导致 Doxygen 无法将生成的文档写入该文件夹。请确保您的输出文件夹具有适当的权限。。
该回答引用GPTᴼᴾᴱᴺᴬᴵ
Doxygen 是一个自动化的文档生成工具,可以通过解析代码中的注释来生成文档。对于 C 语言文件,Doxygen 能够解析函数、变量、宏定义等的注释,生成对应的文档,同时也能够解析文件头部的注释。
在给出的代码中,已经包含了函数和文件头部的注释,因此 Doxygen 可以正确地解析这个 C 文件。您可以按照以下步骤使用 Doxygen 生成文档:
1.安装 Doxygen 工具:您可以在 Doxygen 的官网上下载并安装 Doxygen 工具。
2.创建配置文件:您可以在命令行中输入以下命令来创建 Doxygen 配置文件:
doxygen -g configFileName
其中 configFileName 为您要创建的配置文件名。
3.配置文件:打开生成的配置文件,找到以下几个参数并进行配置:
PROJECT_NAME = "My Project"
PROJECT_NUMBER =
PROJECT_BRIEF = "My brief project description"
INPUT = /path/to/my/code
4.生成文档:在命令行中输入以下命令,即可生成文档:
doxygen configFileName
其中 configFileName 是您在第二步中创建的配置文件名。
5.查看文档:生成的文档位于 Doxygen 工具生成的目录下,您可以打开 index.html 查看文档。
在代码中,注释需要按照特定的格式书写,以便 Doxygen 正确地解析并生成文档。例如,您在代码中使用了以下注释:
/**
* @fn getName
* @brief Get the name of the team.
* @param team The team you specify.
* @return The name of the team.
*/
这段注释用于描述 getName 函数。其中 @fn 表示这是一个函数,@brief 表示这是函数的简要描述,@param 表示函数的参数,@return 表示函数的返回值。在您的代码中,如果您希望 Doxygen 解析出更多的信息,可以参考 Doxygen 的官方文档,并按照文档中的格式书写注释。
https://blog.csdn.net/sanlinux/article/details/6074283
参考GPT和自己的思路:Doxygen 是一个文档生成器,可以从源代码中提取注释和特殊标记并生成文档。在这个 C 代码中,有一些函数和结构体有注释和标记,可以通过 Doxygen 进行解析和生成文档。
在代码中,已经使用了一些 Doxygen 标记:
/**< 和 */ :表示一个文档注释块的开始和结束。
@brief :标记一个函数或者类型的简要描述。
@param :标记一个函数的参数。
@return :标记一个函数的返回值。
@fn :标记一个函数。
@typedef :标记一个类型定义。
此外,还有一些 Doxygen 指令:
@file :指定当前注释块对应的源代码文件。
@def :定义一个宏。
@var :定义一个全局变量。
如果需要使用 Doxygen 来生成文档,需要创建一个配置文件并进行相关的配置,然后运行 Doxygen 命令即可。例如,在 Linux 系统上,可以执行以下命令:
doxygen -g config_file
doxygen config_file
第一个命令会创建一个名为 config_file 的默认配置文件,第二个命令会使用这个配置文件来生成文档。文档会保存在 html 目录下,可以通过浏览器打开查看。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,检查您的Doxygen版本是否正确安装和配置了。您可以在终端中输入doxygen --version来检查版本。
其次,检查您的Doxygen配置文件是否正确设置。通常,您需要使用doxygen -g来生成默认配置文件Doxyfile,并根据您的代码库进行相应的更改。
一些可能需要设置的内容:
还要注意,在Doxygen配置文件中,您需要将C支持设置为YES,以处理C代码。
最后,当您在终端中运行Doxygen命令时,确保使用正确的配置文件。您可以使用doxygen config_file_name命令来指定配置文件。如果您只键入doxygen命令,则Doxygen将查找名为Doxyfile的默认配置文件。
如果我的回答解决了您的问题,请采纳!