I have this code for deleting directories. I have header1.h, header1.c, main.c.
I get some errors, but the one is more difficult to me to understand is the errors:
(1) storage size of ffblk isn't known.
Also, i have the doubt of how to define the attributes of ffblk, which are ff_name and ff_attrib
This example is from various code examples from the internet(even other from here), all of them do the same code, just in my case it does not work.
Am i missing the definition of the struct? or maybe i have added code where it should not be any code?
Could you please help me? I dont usually program in C. and i am using Dev-Cpp.
header1.h:
#ifndef HEADER1_H_INCLUDED
#define HEADER1_H_INCLUDED
typedef struct ffblk ffblk;
#endif
header.c:
#include <stdio.h>
#include <stdlib.h>
#include "header1.h"
struct ffblk
{
char ff_attrib[20]; //this line i added just so dont show error of unknown
char ff_name[20]; //this line i added just so dont show error of unknown
};
main.c:
#ifndef FA_RDONLY
#define FA_RDONLY _A_RDONLY
#endif
#ifndef FA_HIDDEN
#define FA_HIDDEN _A_HIDDEN
#endif
#ifndef FA_SYSTEM
#define FA_SYSTEM _A_SYSTEM
#endif
#ifndef FA_DIREC
#define FA_DIREC _A_SUBDIR
#endif
#ifndef FA_ARCH
#define FA_ARCH _A_ARCH
#endif
# include <stdio.h>
# include <dos.h>
# include <dir.h>
# include <io.h>
# include <conio.h>
#include "header1.h"
typedef struct ffblk ffblk;
int BorrarArchivo(char *nombarch)
{
printf("Borrando Archivo %s \n",nombarch);
remove(nombarch);
return 0;
}
int EliminarAtributo(char *nombarch,int atributo)
{
printf("Elimina Atributo %s %d\n",nombarch,atributo);
chmod(nombarch,atributo);
return 0;
}
int BorrarArbol(void)
{
struct ffblk ffblk;
int done,err;
err=0;
done=findfirst("*.*",&ffblk,FA_RDONLY|FA_HIDDEN|FA_DIREC|FA_ARCH|FA_SYSTEM);
while (!done)
{
if (FA_HIDDEN & ffblk.ff_attrib)
EliminarAtributo(ffblk.ff_name,FA_HIDDEN);
if (FA_SYSTEM & ffblk.ff_attrib)
EliminarAtributo(ffblk.ff_name,FA_SYSTEM);
if (FA_RDONLY & ffblk.ff_attrib)
EliminarAtributo(ffblk.ff_name,FA_RDONLY);
if (FA_ARCH & ffblk.ff_attrib)
err=BorrarArchivo(ffblk.ff_name);
else if (FA_DIREC & ffblk.ff_attrib)
{
if (ffblk.ff_name[0]!='.')
{
chdir(ffblk.ff_name);
err=BorrarArbol();
chdir("..");
if (!err)
printf("Removiendo %s\n",ffblk.ff_name);
rmdir(ffblk.ff_name);
}
}
else
err=BorrarArchivo(ffblk.ff_name);
if (err)
{
printf("Error en el borrado ... !"); return err;
}
done=findnext(&ffblk);
}
return 0;
}
int main (void)
{ int err=0;
char c;
printf("Esta seguro [ Si -> S , No ->otra tecla ] =>");
c=getchar();
if (!(c=='S' || c=='s')) return 0;
err=BorrarArbol();
if (err) printf("Error en el borrado ... !");
return err;
}
EDIT:
I found a definition of struct and paste it in header.h
typedef struct ffblk {
char lfn_magic[6]; /* LFN: the magic "LFN32" signature */
short lfn_handle; /* LFN: the handle used by findfirst/findnext */
unsigned short lfn_ctime; /* LFN: file creation time */
unsigned short lfn_cdate; /* LFN: file creation date */
unsigned short lfn_atime; /* LFN: file last access time (usually 0) */
unsigned short lfn_adate; /* LFN: file last access date */
char ff_reserved[5]; /* used to hold the state of the search */
unsigned char ff_attrib; /* actual attributes of the file found */
unsigned short ff_ftime; /* hours:5, minutes:6, (seconds/2):5 */
unsigned short ff_fdate; /* (year-1980):7, month:4, day:5 */
unsigned long ff_fsize; /* size of file */
char ff_name[260]; /* name of file as ASCIIZ string */
}ffblk;
now it shows error:
C:\Users\1\AppData\Local\Temp\cc89P309.o:Untitled3.c:(.text+0x8e): undefined reference to `findfirst'
C:\Users\1\AppData\Local\Temp\cc89P309.o:Untitled3.c:(.text+0x1d8): undefined reference to `findnext'
At the end, the problem was always the functions findfirst(a,b,c) and findnext(a,b,c). I had to change the functions and use their version with 2 parameters and not 3. I put all the code in one file with the includes, typedef struct and the code below.
Related
tmp2.c
/*
gcc -Wall -Werror -g assert.c tmp2.c && ./a.out
*/
#include "tmp2.h"
#include <assert.h>
int main(void)
{
// assert(1 == 2);
Assert(1 == 2);
return 0;
}
tmp2.h
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <math.h>
#include<stdint.h>
#include<stdalign.h>
#include<stdbool.h>
/*
* BoolIsValid
* True iff bool is valid.
*/
#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true)
/*
* PointerIsValid
* True iff pointer is valid.
*/
#define PointerIsValid(pointer) ((const void*)(pointer) != NULL)
extern void
ExceptionalCondition(const char *conditionName,
const char *fileName,
int lineNumber);
/*
* USE_ASSERT_CHECKING, if defined, turns on all the assertions.
* - plai 9/5/90
*
* It should _NOT_ be defined in releases or in benchmark copies
*/
/*
* Assert() can be used in both frontend and backend code. In frontend code it
* just calls the standard assert, if it's available. If use of assertions is
* not configured, it does nothing.
*/
#define USE_ASSERT_CHECKING 0
#ifndef USE_ASSERT_CHECKING
#define Assert(condition) ((void)true)
#define AssertMarcod(condition) ((void)true)
#elif defined(FRONTEND)
#include<assert.h>
#define Assert(p) assert(p)
#define AssertMarco(p) ((void) assert(p))
#else
/*
* Assert
* Generates a fatal exception if the given condition is false.
*/
#define Assert(condition) \
do { \
if (!(condition)) \
ExceptionalCondition(#condition,__FILE__,__LINE__); \
} while (0)
/*
* AssertMacro is the same as Assert but it's suitable for use in
* expression-like macros, for example:
*
* #define foo(x) (AssertMacro(x != 0), bar(x))
*/
#define AssertMacro(condition) \
((void) ((condition) || \
(ExceptionalCondition(#condition,__FILE__,__LINE__),0)))
#endif
assert.c
#include "tmp2.h"
#include <unistd.h>
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif
/*
* ExceptionalCondition - Handles the failure of an Assert()
*
* We intentionally do not go through elog() here, on the grounds of
* wanting to minimize the amount of infrastructure that has to be
* working to report an assertion failure.
*/
void
ExceptionalCondition(const char *conditionName,
const char *fileName,
int lineNumber)
{
/* Report the failure on stderr (or local equivalent) */
if (!PointerIsValid(conditionName)
|| !PointerIsValid(fileName))
fprintf(stderr,"TRAP: ExceptionalCondition: bad arguments in PID %d\n",
(int) getpid());
else
fprintf(stderr,"TRAP: failed Assert(\"%s\"), File: \"%s\", Line: %d, PID: %d\n",
conditionName, fileName, lineNumber, (int) getpid());
/* Usually this shouldn't be needed, but make sure the msg went out */
fflush(stderr);
// /* If we have support for it, dump a simple backtrace */
// #ifdef HAVE_BACKTRACE_SYMBOLS
// {
// void *buf[100];
// int nframes;
// nframes = backtrace(buf, lengthof(buf));
// backtrace_symbols_fd(buf, nframes, fileno(stderr));
// }
// #endif
/*
* If configured to do so, sleep indefinitely to allow user to attach a
* debugger. It would be nice to use pg_usleep() here, but that can sleep
* at most 2G usec or ~33 minutes, which seems too short.
*/
#ifdef SLEEP_ON_ASSERT
sleep(1000000);
#endif
abort();
}
In this context, I'm trying a way to use the AssertMacro; that is, find a way to invoke assert.c ExceptionalCondition function. Assume FRONTEND is not defined. USE_ASSERT_CHECKING can be 1 or 0.
update: to use ExceptionalCondition function I need to declare it on tmp2.h via
extern void
ExceptionalCondition(const char *conditionName,
const char *fileName,
int lineNumber);
I also need to define USE_ASSERT_CHECKING in tmp2.h or before tmp2.h.
If I don't define USE_ASSERT_CHECKING seems all the assert will be true always?
I am trying to find a way to dynamically access a certain macro in C.
I tried to include the macro in the struct but then I get the "initializer element is not constant" error. Basically I just want to access the correct macro based on an index but I just don't know how. Is there a straight forward way of accomplishing this? Please note the code is not complete but only an illustration of what I want to do.
#define Data_CAN_SES_Enbl() (...)
#define Data_CAN_SAS_Enbl() (...)
#define Data_CAN_PEP_Enbl() (...)
struct CAN_Rx {
const uint8 id;
const uint8 bus;
xx
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,0,?
},
/* SAS */
{
1,0,?
},
/* PEP */
{
2,1,?
}
};
void run(uint8 index)
{
uint8 enabled = CheckRx[index].xx;
}
Simply put: you won't.
Dont think of macros as code: they're just chunk of text replaced by the preprocessor before compiling your code.
If you need to embed code in a struct, you better look at function pointers.
--- EDIT ---
By the way, why you want to use macro in your code? Looking at it, it seems you cand do the same thing with a simple function returning a struct with a different content based on a parameter, like:
static struct CAN_Rx getCANrx(int index){
switch(index)
{
case '0':
struct CAN_rx res = /* initialize struct */;
return res;
case '1':
/* as previous */
default:
/* manage default result or errors */
}
}
Maybe you can go with function pointers?
#include <stdio.h>
int Data_CAN_SES_Enbl() { return 0; }
int Data_CAN_SAS_Enbl() { return 1; }
int Data_CAN_PEP_Enbl() { return 2; }
struct CAN_Rx {
const int id;
const int bus;
int (*xx)();
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,0,Data_CAN_SES_Enbl
},
/* SAS */
{
1,0,Data_CAN_SAS_Enbl
},
/* PEP */
{
2,1,Data_CAN_PEP_Enbl
}
};
int run(int index)
{
int enabled = (*CheckRx[index].xx)();
return enabled;
}
int main() {
printf("%d\n",run(0));
}
If you are curious see below macro example.
For your case , macro cant be better than function pointers.
Using macro just for fun at your case.
#include <stdio.h>
#include <stdlib.h>
#define Data_CAN_SES_Enbl(Y,Z) Y+Z
#define Data_CAN_SAS_Enbl(Y,Z) Y*Z
#define Data_CAN_PEP_Enbl(Y,Z) Y-Z
#define Str(X) #X
#define Data_CAN_Enbl(X,Y,Z) Data_CAN_##X##_Enbl(Y,Z);
#define SES 1
#define SAS 2
#define PEP 3
struct CAN_Rx {
int id;
int bus;
int Flag;
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,100,SES
},
/* SAS */
{
70,20,SAS
},
/* PEP */
{
100,50,PEP
}
};
void run(int index)
{
int RRR=0;
switch(CheckRx[index].Flag){
case SES:
RRR=Data_CAN_Enbl(SES,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(SES),RRR);
break;
case SAS:
RRR=Data_CAN_Enbl(SAS,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(SAS),RRR);
break;
case PEP:
RRR=Data_CAN_Enbl(PEP,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(PEP),RRR);
break;
}
}
int main(){
run(0);
run(1);
run(2);
printf("%d\n",CheckRx[0].Flag);
return 0;
}
I'd need some help with structs in C.
Basically I'm trying to create a Student and a Group struct definition.
Keep in mind that Group struct will contain Student structs previously implemented.
Below my structs definition:
Student Struct: student.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEFAULT_MATRICOLA 815010
typedef struct Student{
int matricola;
int voto_archi;
char *turno;
}Student;
int generateVoto(){
return (rand() % (30 - 18)) + 18;
}
char* generateTurno(int matricola){
char *res = malloc(2*sizeof(char) + 1);
if(matricola % 2 == 0)
res = "T2";
else
res = "T1";
return res;
}
void initializeStudent(Student s, int matricola){
s.matricola = matricola;
s.voto_archi = generateVoto();
if(s.matricola % 2 == 0){
strcpy(s.turno, "T2");
}
else{
strcpy(s.turno, "T1");
}
}
void showStudent(Student s){
printf("Matricola: %d Voto: %d Turno: %s\n", s.matricola, s.voto_archi, s.turno);
}
Student createStudent(int matricola){
int voto = generateVoto();
char *turno = generateTurno(matricola);
Student s = {matricola, voto, turno};
return s;
}
Group Struct: group.h
#include "headers.h"
#include "student.h"
#define MAX_MEMBERS 4
typedef struct Group{
int groupId;
Student *members;
int numMembers;
boolean closed;
}Group;
Group createGroup(int groupId){
Group g;
g.groupId = groupId;
g.members = malloc(MAX_MEMBERS * sizeof(Student) + 1);
g.numMembers = 0;
g.closed = FALSE;
return g;
}
void printGroup(Group g){
int index = g.numMembers;
if(index == 0)
printf(RED "Group %d is EMPTY\n" RESET, g.groupId);
else{
for(int i = 0; i < MAX_MEMBERS; i++)
showStudent(g.members[i]);
printf("\n");
}
}
Now even an empty main.c class containing only #include "student.h and #include "group.h would fail compiling but if we only add one of these two it works good.
Here's compiler's output:
Now, at last, my question:
How to create a main.c class using both student.h and group.h files?
What am I doing wrong?
You need to wrap all your header files in "include guards" so that if the header content has already been included, in any subsequent inclusion the content is skipped to prevent redefinitions:
For example for group.h you might have:
#if !defined GROUP_H
#define GROUP_H
// all Header file content here...
#endif // GROUP_H
where the macro (GROUP_H) in this case must be unique throughout teh project - it is conventional to use a name based on the file name.
An alternative supported by many toolchaisn is to use the #pragma once directive:
#pragma once
// all Header file content here...
This is less portable, but more fool-proof that a traditional include guard.
Now even an empty main.c class containing only #include "student.h and #include "group.h would fail compiling but if we only add one of these two it works good.
Apparently you lack the guard to protect your header files, which look something like this (for each .h file):
#ifndef STUDENT_H
#define STUDENT_H
// your header file goes here
#endif STUDENT_H
Alternately, you can use #pragma once at the beginning of each header file (which is supposedly a better and shorter way).
I am learning to write my own Virtual File system but besides the logical error in program something other than that keeps coming i checked all the declarations within the program but couldn't figure it out.
helper function
#include "header.h"
UFDT UFDTArr[50];
SUPERBLOCK SUPERBLOCKobj;
PINODE head=NULL;
void man(char *name)
{
if(name==NULL) return;
if(_stricmp(name,"ls")==0)
{
printf("Description : Used to list all information of file\n");
printf("Usage : ls\n");
}
else
{
printf("ERROR : No manual entry available\n");
}
}
void DisplayHelp()
{
printf("ls : To List Out all files \n");
printf("clear : To Clear consol\n");
}
void CreateDILB()
{
PINODE newn=NULL;
PINODE temp=head;
int i=1;
while(i<=MAXINODE)
{
newn=(PINODE)malloc(sizeof(INODE));
newn->LinkCount=newn->ReferenceCount=0;
newn->FileType=newn->FileSize=0;
newn->Buffer=NULL;
newn->next=NULL;
newn->InodeNumber=i;
if(temp==NULL)
{
head=newn;
temp=head;
}
else
{
temp->next=newn;
temp=temp->next;
}
i++;
}
}
void InitialiseSuperBlock()
{
int i=0;
while(i<50)
{
UFDTArr[i].ptrfiletable=NULL;
i++;
}
SUPERBLOCKobj.TotalInodes=MAXINODE;
SUPERBLOCKobj.FreeInode=MAXINODE;
}
void ls_file()
{
PINODE temp=head;
if(SUPERBLOCKobj.FreeInode== MAXINODE)
{
printf("Error : There are no files ");
return;
}
printf("\n File Name\tInode Number\tFile Size\tLink count\n");
printf("------------------------------------------------------------");
while(temp!=NULL)
{
if(temp->FileType!=0)
{
printf("%s\t\t%d\t\t%d\t\t%d\n");
}
temp=temp->next;
}
printf("------------------------------------------------------------");
}
main file
#include "header.h"
int main()
{
char *ptr=NULL;
int ret=0,fd=0,count=0;
char command[4][80],str[80],arr[1024];
InitialiseSuperBlock();
CreateDILB();
while(1)
{
fflush(stdin);
strcpy_s(str,"");
printf("Sachin VFS :> ");
fgets(str,80,stdin);
count=sscanf(str,"%s%s%s %s",command[0],command[1],command[2],command[3]);
if(count==1)
{
if(_stricmp(command[0],"ls")==0)
{
ls_file();
}
else if(_stricmp(command[0],"clear")==0)
{
system("cls");
continue;
}
else
{
printf("\n ERROR : Command not found!!! \n");
continue;
}
}
}
return 0;
}
header file
#define _CRT_SECURE_NO_WARNINGS
#define MAXINODE 50
#define READ 1
#define WRITE 2
#define MAXFILESIZE 1024
#define REGULAR 1
#define SPECIAL 2
#define START 0
#define CURRENT 1
#define END 2
#include<iostream>
#include <stdlib.h>
#include<string.h>
#include<io.h>
typedef struct superblock
{
int TotalInodes;
int FreeInode;
}SUPERBLOCK,*PSUPERBLOCK;
typedef struct inode
{
char FileName[50];
int InodeNumber;
int FileSize;
int FileActualSize;
int FileType;
char *Buffer;
int LinkCount;
int ReferenceCount;
int permission;
struct inode *next;
}INODE,*PINODE,**PPINODE;
typedef struct filetable
{
int readoffset;
int writeoffset;
int count;
int mode;
PINODE ptrinode;
}FILETABLE,*PFILETABLE;
typedef struct ufdt
{
PFILETABLE ptrfiletable;
}UFDT;
the one solution to this problem i got is declaring all the functions in main file above main to make compiler identify the functions but i still couldn't figure it out why it cant identify the same functions when i declare them in other file?
the default functions are working like system("cls"); but my functions are not working
could anyone help me to understand the reason of this error and possible solution ?
P.S.- I have pasted small part of my code the actual code is too long to post if anyone wants me to post it i will in comment section
In brief - you should declare ls_file() in your header.h:
void ls_file();
This is a common technique to export some objects / functions outside of file where they are defined. Both "implementation" and "client" *.c files must include that header. The former one - in order to guarantee consistency of actual definitions and publicly-visible declarations, the latter one - to provide client code with proper and explicit declarations.
... still couldn't figure it out why it cant identify the same
functions when i declare them in other file?
In general compiler should see declarations or definitions of functions / globals before any referencing to them. This is because during compilation process translator works only with one .c source, and knows nothing about another source files and their content.
P.S This answer may enlighten you a bit more.
In Command Windows, there is an error!
please see below!
In file included from lwIP/test/unit/lwip_unittests.c:1:0:
lwIP/test/unit/lwip_check.h:7:19: fatal error: check.h: No such file or directory
compilation terminated.
make: *** [obj/lwIP/test/unit/lwip_unittests.o] Error 1
I am using an Sourcery_2011_09_ARM_EABI.
But in this files there isn't header file names check.h
In the file lwip_unittests.c:
#ifndef __LWIP_CHECK_H__
#define __LWIP_CHECK_H__
/* Common header file for lwIP unit tests using the check framework */
#include <sys/config.h>
#include <check.h>
#include <stdlib.h>
#define FAIL_RET() do { fail(); return; } while(0)
#define EXPECT(x) fail_unless(x)
#define EXPECT_RET(x) do { fail_unless(x); if(!(x)) { return; }} while(0)
#define EXPECT_RETX(x, y) do { fail_unless(x); if(!(x)) { return y; }} while(0)
#define EXPECT_RETNULL(x) EXPECT_RETX(x, NULL)
/** typedef for a function returning a test suite */
typedef Suite* (suite_getter_fn)(void);
/** Create a test suite */
static Suite* create_suite(const char* name, TFun *tests, size_t num_tests, SFun setup, SFun teardown)
{
size_t i;
Suite *s = suite_create(name);
for(i = 0; i < num_tests; i++) {
/* Core test case */
TCase *tc_core = tcase_create("Core");
if ((setup != NULL) || (teardown != NULL)) {
tcase_add_checked_fixture(tc_core, setup, teardown);
}
tcase_add_test(tc_core, tests[i]);
suite_add_tcase(s, tc_core);
}
return s;
}
#endif /* __LWIP_CHECK_H__ */
I need a file check.h, where can i get this?
And if check.h will be implemented in the file Sourcery_2011_09_ARM_EABI, will it work?
Or do i need to change check.h to tree-check.h or something other named, that is implement in the Sourcery_2011_09_ARM_EABI?
You'll probably need to install the check unit testing framework: http://check.sourceforge.net/