Working with pointers in C - c

I have created this program in c. The user type 'lieunaissance' and then we open a formatted file to search 'lieunaissance' value.
I had a problem with the file, but now, my problem is with my structure struct departement *recherche_dpt(char recherche_code[]), it always returns CODE_NON_TROUVE = 0.
How should I solve this, please?
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<stddef.h>
#include <errno.h>
#define MAX_dpt 100000
#define KEY_NOT_FOND "NOT_FOUND"
/* global statement */
struct departement
{
char currentCode[10];
char oldCode[10];
char name[50];
struct departement *predecesseur ;
struct departement *successeur;
};
struct departement *debut_liste, *fin_liste;
struct departement *undepartement();
void ouvrir_fichier(char Nomfichier[]);
struct departement *search_dpt(char recherche_code[]);
struct departement tabdpt[MAX_dpt];
int main()
{
char sexe, reponse, date[5], annee[3], mois[4], bidon[3],birthPlace[30], ordre[4], struct1[6], struct2[6],nir1[12],nir[13],nir2[13], nirancien[13] ;
int i, namebre, cle, reste,n;
long int val;
struct departement undpt, *pointeur;
char code[10];
scanf("%s",birthPlace);
// convert birthplace uppercase and assign it to name
int k = 0;
while(birthPlace[k])
{
birthPlace[k] = toupper(birthPlace[k]);
k++;
}
printf("%s\n", birthPlace);
// Read in the file
ouvrir_fichier("Basedecommunes.txt");
pointeur=search_dpt(birthPlace);
undpt = *pointeur;
if (strcmp(undpt.currentCode,KEY_NOT_FOND)==0)
{
printf("No ""%s"" has been found \n",birthPlace);
}
else
{
printf("Current code : %s\n",undpt.currentCode);
printf("Old code : %s\n",undpt.oldCode);
printf("Department name : %d\n",undpt.name);
}
void ouvrir_fichier(char Nomfichier[])
{
struct departement *ptmp, *prec, *succ;
FILE *f1;
int nb, lire;
nb=0;
f1=fopen(Nomfichier, "r" );
if (f1 == NULL) {
printf("fopen failed, errno = %d\n", errno);
}
else {
printf("fopen succeeded\n");
while ((! feof(f1)) && (nb < MAX_dpt) )
{
ptmp=undepartement();
if (ptmp != NULL) {
lire=fscanf (f1, "%s %s %s", (*ptmp).currentCode, (*ptmp).oldCode, (*ptmp).name);
printf("lire = %d\n",lire);
if (lire != EOF)
{
(*ptmp).predecesseur=NULL ;
(*ptmp).successeur=NULL;
if (debut_liste == NULL)
{
debut_liste=ptmp ;
fin_liste=ptmp ;
}
else
{
(*fin_liste).successeur=ptmp ;
(*ptmp).predecesseur=fin_liste ;
fin_liste=ptmp ;
}
nb++ ;
}
} else {
printf("malloc error\n");
}
}
}
fclose(f1);
}
/*--- fonction de recherche --- */
struct departement *search_dpt(char dep_name[])
{
struct departement ptmp, *pointeur, *pactu;
int trouve ;
trouve = 0 ;
pointeur=undepartement();
strcpy((*pointeur).currentCode, KEY_NOT_FOND);
pactu=debut_liste ;
while ((! trouve) && (pactu != NULL))
{
ptmp = (*pactu) ;
pactu=(*pactu).successeur ;
trouve=((strcmp(ptmp.currentCode,dep_name))==0) ;
if (trouve)
{
*pointeur=ptmp ;
}
}
return pointeur;
}
/* --- allocation memoire d'une nouvelle structure --- */
struct departement * undepartement(void)
{
struct departement *p = malloc(sizeof *p);
return p;
}
The file content:
01001 01001 ABERGEMENT-CLEMENCIAT
01002 01002 ABERGEMENT-DE-VAREY
01003 01003 AMAREINS
01004 01004 AMBERIEU-EN-BUGEY
01005 01005 AMBERIEUX-EN-DOMBES
01006 01006 AMBLEON
01007 01007 AMBRONAY
01008 01008 AMBUTRIX
01009 01009 ANDERT-ET-CONDON
01010 01010 ANGLEFORT
01011 01011 APREMONT
01012 01012 ARANC
01013 01013 ARANDAS
01014 01014 ARBENT
01015 01015 ARBIGNIEU
01016 01016 ARBIGNY

In your code,
strcpy((*pointeur).codeactuel, CODE_NON_TROUVE);
codeactuel is defined to have a size of 10, but to copy CODE_NON_TROUVE you need to have a size of 11.
Then, printf(birthPlace); is also wrong, it should be something like
printf("%s\n", birthPlace);
Also, there is a logical problem in
pointeur=undepartement();
if malloc() fails and undepartement() returns NULL, you'll be facing undefined behaviour by dereferencing pointeur. Please add a NULL check.
P.S - There maybe other issues. Please provide a MCVE and if possible kindly stick to english so that we can understand the code logic in a better way.

Inside while loop you are comparing .currentCode with .dep_name.
This was wrong. Change the code to this:
// trouve=((strcmp(ptmp.currentCode,dep_name))==0) ;
trouve=((strcmp(ptmp.name,dep_name))==0) ;
And it works correct.

Related

How to use the ARM PMU in GEM5?

I had a problem initializing the PMU in gem5 for an arm full system with the starter_fs.py in --cpu hpi.
i followed the instructions of this post Using perf_event with the ARM PMU inside gem5 and i managed to solve my problem. I added the patch and configure the system. I am not using perf. I try to access directly the registers and read them. As i see GEM5 has only some register events implemented. Can we add the others as well as :
for example EXC_TAKEN is not implemented. Is the following the way to add them?
self.addEvent(ProbeEvent(self,0x09, cpu, "EXC_TAKEN"))
#0x09: EXC_TAKEN ???
Also, reading the pmu event registers i manage to read them and extract the events but the pmccntr cycle register always returns zero? How gem5 increments this register? What are the steps to read the cycle reggister?
a code that i use to read using perf is the following:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/perf_event.h>
#define NUM_NODES 100
#define NONE 9999
struct _NODE
{
int iDist;
int iPrev;
};
typedef struct _NODE NODE;
struct _QITEM
{
int iNode;
int iDist;
int iPrev;
struct _QITEM *qNext;
};
typedef struct _QITEM QITEM;
QITEM *qHead = NULL;
int AdjMatrix[NUM_NODES][NUM_NODES];
int g_qCount = 0;
NODE rgnNodes[NUM_NODES];
int ch;
int iPrev, iNode;
int i, iCost, iDist;
void print_path (NODE *rgnNodes, int chNode)
{
if (rgnNodes[chNode].iPrev != NONE)
{
//print_path(rgnNodes, rgnNodes[chNode].iPrev);
}
//printf (" %d", chNode);
fflush(stdout);
}
void enqueue (int iNode, int iDist, int iPrev)
{
QITEM *qNew = (QITEM *) malloc(sizeof(QITEM));
QITEM *qLast = qHead;
if (!qNew)
{
//fprintf(stderr, "Out of memory.\n");
exit(1);
}
qNew->iNode = iNode;
qNew->iDist = iDist;
qNew->iPrev = iPrev;
qNew->qNext = NULL;
if (!qLast)
{
qHead = qNew;
}
else
{
while (qLast->qNext) qLast = qLast->qNext;
qLast->qNext = qNew;
}
g_qCount++;
// ASSERT(g_qCount);
}
void dequeue (int *piNode, int *piDist, int *piPrev)
{
QITEM *qKill = qHead;
if (qHead)
{
// ASSERT(g_qCount);
*piNode = qHead->iNode;
*piDist = qHead->iDist;
*piPrev = qHead->iPrev;
qHead = qHead->qNext;
free(qKill);
g_qCount--;
}
}
int qcount (void)
{
return(g_qCount);
}
int dijkstra(int chStart, int chEnd)
{
for (ch = 0; ch < NUM_NODES; ch++)
{
rgnNodes[ch].iDist = NONE;
rgnNodes[ch].iPrev = NONE;
}
if (chStart == chEnd)
{
//printf("Shortest path is 0 in cost. Just stay where you are.\n");
}
else
{
rgnNodes[chStart].iDist = 0;
rgnNodes[chStart].iPrev = NONE;
enqueue (chStart, 0, NONE);
while (qcount() > 0)
{
dequeue (&iNode, &iDist, &iPrev);
for (i = 0; i < NUM_NODES; i++)
{
if ((iCost = AdjMatrix[iNode][i]) != NONE)
{
if ((NONE == rgnNodes[i].iDist) ||
(rgnNodes[i].iDist > (iCost + iDist)))
{
rgnNodes[i].iDist = iDist + iCost;
rgnNodes[i].iPrev = iNode;
enqueue (i, iDist + iCost, iNode);
}
}
}
}
//printf("Shortest path is %d in cost. ", rgnNodes[chEnd].iDist);
//printf("Path is: ");
//print_path(rgnNodes, chEnd);
//printf("\n");
}
}
int main(int argc, char *argv[]) {
int diff = 0;
uint64_t num_cycles_nominal=0;
uint64_t num_cycles_attack=0;
uint64_t counter_cpu_cycles = 0;
//system("./load-module");
int i,j,k;
FILE *fp;
static int perf_fd_cpu_cycles;
static struct perf_event_attr attr_cpu_cycles;
attr_cpu_cycles.size = sizeof(attr_cpu_cycles);
attr_cpu_cycles.exclude_kernel = 1;
attr_cpu_cycles.exclude_hv = 1;
attr_cpu_cycles.exclude_callchain_kernel = 1;
attr_cpu_cycles.type = PERF_TYPE_RAW;
attr_cpu_cycles.config = 0x11;
/* Open the file descriptor corresponding to this counter. The counter
should start at this moment. */
if ((perf_fd_cpu_cycles = syscall(__NR_perf_event_open, &attr_cpu_cycles, 0, -1, -1, 0)) == -1)
fprintf(stderr, "perf_event_open fail %d %d: %s\n", perf_fd_cpu_cycles, errno, strerror(errno));
if (argc<2) {
//fprintf(stderr, "Usage: dijkstra <filename>\n");
//fprintf(stderr, "Only supports matrix size is #define'd.\n");
}
/* open the adjacency matrix file */
fp = fopen (argv[1],"r");
/* make a fully connected matrix */
for (i=0;i<NUM_NODES;i++) {
for (j=0;j<NUM_NODES;j++) {
/* make it more sparce */
fscanf(fp,"%d",&k);
AdjMatrix[i][j]= k;
}
}
/* Get and close the performance counters. */
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
//close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles before: %d\n", counter_cpu_cycles);
num_cycles_nominal = counter_cpu_cycles;
/* Get and close the performance counters. */
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
//close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles after attack: %d\n", counter_cpu_cycles);
num_cycles_attack = counter_cpu_cycles - num_cycles_nominal;
/* finds 10 shortest paths between nodes */
for (i=0,j=NUM_NODES/2;i<100;i++,j++) {
j=j%NUM_NODES;
dijkstra(i,j);
}
read(perf_fd_cpu_cycles, &counter_cpu_cycles, sizeof(counter_cpu_cycles));
close(perf_fd_cpu_cycles);
printf("Number of cpu_cycles end: %d\n", counter_cpu_cycles);
num_cycles_nominal = counter_cpu_cycles - num_cycles_attack;
printf("Number of cpu_cycles nominal: %d\n", num_cycles_nominal);
printf("Number of cpu_cycles attack: %d\n", num_cycles_attack);
exit(0);
}
the problem is that i can read the branch misses with perf having 0x10 instead 0f 0x11 (cycle counters RAW EVENT in GEM5) but using 0x11 for reading the cycles i get zero. When i try to reverse engineer the increment of cycle counter i do the following comments:
when simple/atomic or simple/timing i see that updateCycleCounter is called from the base.hh, also for the 03 cpu model. When HPI and considering that hpi is a MinorCPU model i see that updateCycleCounter is called only in POWER_STATE_ON, but i didnt find in the code a POWER_STATE_ON reference updateCycleCounter(CPU_STATE_ON) which will update the cycle counter. Please help me verify this assumption.
*****The problem was that in the MinorCPU the updateCycleCounter wasnt called for the CPU_STATE_ON which updates the ActiveCycles. It was fixed by the following patch https://gem5-review.googlesource.com/c/public/gem5/+/38095 .

Trying to compile a x86 C program on a x64 RedHat environment [Part 2]

Still following the saga of a Cobol developer handling C programs on a environment migration.
I think we could manage 90% of the problems so far and most of our C programs are now compiling fine on the RHEL 64 bits.
Friday we found another module that is not compiling and I hope to be the last one.
I am receiving two warnings, but I have no idea about it and our make does not allow us to compile it properly.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <memory.h>
#include <errno.h>
#include </public/prod/src/mfqinc.h>
static FILE *infile = NULL;
static FILE *outfile = NULL;
char inbuf[1024], blockrec[10240];
static char workstring[1024];
static char workstring0[1024];
static char gra2533h [8];
static char gra2401h [8] ;
static char gra2501h [8] ;
static char gra2506h [8] ;
static char crtn[1] ; /* {"0x0A"};*/
int i;
int z;
int f;
int resulisn;
int j;
int d;
int ctrrec;
int nb_ecrit;
static int longueur;
void initworkstring()
{
extern char workstring [1024];
int ik;
for (ik=0; ik < 1024 ;ik++)
{
workstring [ik] = NULL;
}
}
void ecriture()
{
extern char workstring [1024];
extern int longueur;
extern int ctrrec;
nb_ecrit = fwrite(workstring,sizeof(char),longueur,outfile);
ctrrec++;
if ( nb_ecrit != longueur )
{
printf("andlog:erreur d ecriture ");
printf("Ecrit: %i",nb_ecrit);
printf("Erreur no: %i",errno);
exit(60);
}
}
static void errarg(char *errmsg)
{
fprintf(stderr,"ERROR - %s\nCommand format :\n\t",errmsg);
fprintf(stderr," : \n");
/* exit(1); */
}
main (int argc, char *argv[])
{
if ( argc < 3 )
{
printf("<<< Programme : and015 >>>\n");
printf("<<< Nombre de parametres incorrect >>>\n");
printf("<<< Remove catacteres speciaux >>>\n");
printf("<<< Param # 1 = nom du fichier d'input >>>\n");
printf("<<< Param # 2 = nom du fichier d'output >>>\n");
printf("\n");
exit(10);
}
if ((infile = fopen(argv[1],"rb")) == NULL )
{
printf("Erreur sur fichier input \n");
exit(20);
}
if ((outfile = fopen(argv[2],"wb")) == NULL )
{
printf("Erreur sur fichier output \n");
exit(30);
}
initworkstring();
/* remplir les table de catacteres */
crtn[0]=0x0a;
gra2533h[0]=0x1b;
gra2533h[1]=0x5b;
gra2533h[2]=0x32;
gra2533h[3]=0x35;
gra2533h[4]=0x3b;
gra2533h[5]=0x33;
gra2533h[6]=0x33;
gra2533h[7]=0x48;
gra2401h[0]=0x1b;
gra2401h[1]=0x5b;
gra2401h[2]=0x32;
gra2401h[3]=0x34;
gra2401h[4]=0x3b;
gra2401h[5]=0x30;
gra2401h[6]=0x31;
gra2401h[7]=0x48;
gra2501h[0]=0x1b;
gra2501h[1]=0x5b;
gra2501h[2]=0x32;
gra2501h[3]=0x35;
gra2501h[4]=0x3b;
gra2501h[5]=0x30;
gra2501h[6]=0x31;
gra2501h[7]=0x48;
gra2506h[0]=0x1b;
gra2506h[1]=0x5b;
gra2506h[2]=0x32;
gra2506h[3]=0x35;
gra2506h[4]=0x3b;
gra2506h[5]=0x30;
gra2506h[6]=0x36;
gra2506h[7]=0x48;
while (fgets(inbuf,1024,infile) != NULL )
{
i=0;
j=0;
d=0;
for (i=0; i < 1024 ; i++)
{
if ( inbuf [i] == NULL )
{
i = 9999;
}
else
{
if ( inbuf[i] == 0x1b )
{
i++;
d=0;
for (d=0 ;d < 8; d++)
{
if ( inbuf[i] == 0x48 )
{
j= j-d;
workstring[j]=0x0a;
d=99;
}
else
{
if (inbuf[i] == 0x6d)
{
j= j-d;
workstring[j]=0x0a;
d=99;
}
else
{
if (inbuf[i] == 0x53)
{
j=j-d;
workstring[j]=0x0a;
d=99;
}
else
{
workstring[j] = inbuf[i];
j++;
i++;
}
}
}
} /* end du for*/
}/*fin du if 01b*/
else
{
workstring[j] = inbuf[i];
j++;
}
}
/* mettre dans workstring */
workstring [j] = inbuf [i];
}
strcat(workstring,crtn);
longueur = j ;
ecriture ();
initworkstring();
} /* fin du while */
fclose(infile);
fclose(outfile);
exit(0);
}
Those are the warnings I am having.
/exp/prod/src>gcc -m64 mfqlog.c -o mfqlog
mfqlog.c: In function 'initworkstring':
mfqlog.c:48:20: warning: assignment makes integer from pointer without a cast [enabled by default]
workstring [ik] = NULL;
^
mfqlog.c: In function 'main':
mfqlog.c:146:18: warning: comparison between pointer and integer [enabled by default]
if ( inbuf [i] == NULL )
Really sorry to bother with this question. But I really need to compile this code.
The funny fact is that the program is working (probably, for some unknown reason to me, the program was compiling before and it is not anymore due to changes on the compiler maybe?!?) on our actual environment, but if we try to compile it will fail and the only way to make it working is restoring the executable backup.
As we are moving to a new 64 bits environment, it has to be recompiled.
Thank you all for the help.
NULL is defined as (void*)0. Replace NULL with '\0' or 0.
workstring [ik] = '\0';
if ( inbuf [i] == '\0' )

pointer when I try to initialize in c

typedef struct Email
{
char domain [128];
char local [128];
} Email ;
Email email_in(char s[])
{
Email *result ;
int c=0;
for(c=0;c<128;c++)
{
result->domain[c]='\0';
result->local[c]='\0';
}
char *ss = s;//PG_GETARG_CSTRING(0);
//result = 0;
int i,j, ind1=0, x=0 , dot=0;
int length= strlen(ss);
for(i=0; i<length;i++)
{
if(ss[i]<='Z' && ss[i]>='A' )
{
ss[i]=ss[i]+32;
}
}
;
if ( ((ss[0]<'a') || (ss[0]>'z')) )
{
if((ss[0]<'A') || (ss[0]>'Z'))
perror("Error printed by perror=1");
}
else
{
for ( i=0;i<length;i++)
{
if (ss[i]=='#')
{
result->local[i]=ss[i];
ind1=i+1;
break;
}
else
if(ss[i]=='-' || ss[i]=='.')
if(ss[i-1]=='-' || ss[i-1]=='.')
{
perror("Error printed by perror=4 ");
}
if ( ((ss[i]<'a') || (ss[i]>'z') )&&((ss[i]<'0')||(ss[i]>'9')) )
{
if(((ss[i]<'A') || (ss[i]>'Z')) &&(ss[i]!='-') &&(ss[i]!='.') )
{
printf("%c \n",ss[i]);
perror("Error printed by perror=2");
}
}
if(ss[i]!='#')
result->local [i]=ss[i];
}
for ( j=ind1;j<length;j++)
{
if(ss[j]=='.')
dot= dot+1;
if(ss[j]=='-' || ss[j]=='.')
if(ss[j-1]=='-' || ss[j-1]=='.')
{
perror("Error printed by perror=6 ");
}
if ( (ss[j]<'a') || ((ss[j]>'z' ) ) )
{
if(((ss[j]<'A') || (ss[j]>'Z')) &&(ss[j]!='-') &&(ss[j]!='.') )
perror("Error printed by perror=3 ");
}
result->domain [x]=ss[j];
x=x+1;
}
result->domain[x+1]='\0';
result->domain[x]='\0';
if(dot<1 && dot >2)
perror("invalid domain");
}
return*(result);//PG_RETURN_POINTER(result);
}
void main()
{
char s1[]="tami#openu.ac.il\0";
email_in(s1);
//printf("%s",s1);
}
When it reach result->domain[c]='\0'; its showed me error
"reslut=null"
I need pointer to change in original copy but how to do it?
this function use to validate email address used in PostgreSQL to add new data type
I have zero experience in c or c++
I need help ><
When you do
Email *result ;
you get a pointer to Email but you don't get an Email variable.
In this case you should avoid pointer and use the struct directly. Something like:
#include <stdio.h>
#include <string.h>
typedef struct Email
{
char domain [128];
char local [128];
} Email ;
Email email_in()
{
Email result; // Don't use pointer
strcpy(result.domain, "test_domain");
strcpy(result.local, "test_local");
return result;
}
int main(void) {
Email x=email_in(); // Make the variable x of type Email
printf("%s\n", x.domain);
printf("%s\n", x.local);
return 0;
}
If you prefer working with pointers, you could try something like:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Email
{
char domain [128];
char local [128];
} Email ;
Email* email_in()
{
Email* result;
result = malloc(sizeof(Email)); // Allocate memory for an Email and make result point to it
strcpy(result->domain, "test_domain");
strcpy(result->local, "test_local");
return result;
}
int main(void) {
Email* x=email_in(); // Make the variable x of type pointer to Email
printf("%s\n", x->domain);
printf("%s\n", x->local);
free(x); // Free the allocated memory
return 0;
}

including header file in two .c files

The program should save a couple of points and put them out on request.
The program contains one .h file and two .c files.
This is the compiler info i get:
prog.c:46:25: fatal error: pointstack.h: No such file or directory #include "pointstack.h"
What did I miss?
//File: pointStack.h - Headerfile
#ifndef POINTSTACK_H
#define POINTSTACK_H
#include <stdio.h>
#include <stdlib.h>
//structs
//struct for coordinates
struct point
{
float rX;
float rY;
float rZ;
};
typedef struct point POINT;
struct stackPoint
{
POINT p;
struct stackPoint *next;
};
typedef struct stackPoint STACK_POINT;
typedef STACK_POINT *STACK_POINT_PTR;
//functions
void push(POINT pushPoint);
POINT pop();
int isEmpty();
void printStackElement(POINT aPoint);
#endif
//File: pointstack.c - functions of stack program
#include "pointstack.h"
//global variable
STACK_POINT_PTR stackTop = NULL;
void push(POINT pushPoint)
{
//temporary variable
STACK_POINT_PTR stackPoint = (STACK_POINT_PTR) malloc(sizeof(STACK_POINT));
//in case there is not enough memory
if(stackPoint == NULL)
{
printf("not enough memory ... End \n");
exit(1);
}
//save point
stackPoint->p = pushPoint;
stackPoint->next = stackTop;
stackTop = stackPoint;
return;
}
POINT pop()
{
//save stackTop and nextStackTop
STACK_POINT firstStackPoint = *stackTop;
free(stackTop);
stackTop = firstStackPoint.next;
return firstStackPoint.p;
}
int isEmpty()
{
if(stackTop == NULL)
{
return 1;
}
else {
return 0;
}
}
void printStackElement(POINT aPoint)
{
printf("Point x: %f, Point y: %f, Point z: %f \n", aPoint.rX, aPoint.rY, aPoint.rZ);
return;
}
//File: stackmain.c
#include "pointstack.h"
void exit(int);
POINT readPoint()
{
POINT userPoint;
printf("x-coordinate \n");
scanf("%62f", &userPoint.rX);
printf("y-coordinate \n");
scanf("%62f", &userPoint.rY);
printf("z-coordinate \n");
scanf("%62f", &userPoint.rZ);
return userPoint;
}
int main(void)
{
//declaration
char cCmd;
printf("’p’ for input, ’q’ for output: \n");
while(1)
{
scanf("%c", &cCmd);
if(cCmd == 'p')
{
push(readPoint());
printf("’p’ for input, ’q’ for output: \n");
}
if(cCmd == 'q')
{
while(!isEmpty())
{
printStackElement(pop());
}
break;
}
}
return 0;
}
What you missed is that your file is called pointStack.h with a capital S, not pointstack.h with a lower case s.

HTML tags check in C

I'm writing a little program in C, for check the HTML file have the right open and close tags?
but i've got some issues...
i have a file what contains the all possible tags, named tags.txt(those are only the first ones):
<a>
</a>
<abbr>
</abbr>
<area>
</area>
<aside>
</aside>
and i have the htmlfile.html, what I have to check:
<!--#echo var="date" -->
<area>
</area>
<area>
</area>
secondly, i want to replace the comments like this to the sysdate
like , the format is OK i can do it, but the prog puts in the file
this
my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_SIZE 512
void menu();
void check();
void datumos();
int main(int argc,char *argv[])
{
menu();
return 0;
}
void menu()
{
char menu[MAX_SIZE];
while(1 < 2)
{
printf("\npress a button:\n\n");
printf("\tFile HTML check..............:c\n");
printf("\t<!--#echo var="date" -->...........:d\n");
printf("\tExit:\tCTRL + C\n");
scanf("%s",menu);
if( strcmp(menu,"c") == 0 )
{
check();
}
else if( strcmp(menu,"d") == 0 )
{
datumos();
}
}
}
void check()
{
FILE *htmlfile;
FILE *checkfile;
htmlfile = fopen("htmlfile.html","w");
checkfile = fopen("tags.txt","r");
char line[MAX_SIZE];
char htmlline[MAX_SIZE];
char tags[189][30];
int i=0;
printf("\tcheck__1\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
int j;
for(j=0; j<sizeof(line); ++j)
{
tags[i][j]=line[j];
}
++i;
}
printf("\tcheck__2\n");
int k=0; char htmlfiletags[MAX_SIZE][30];
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
char currentline[sizeof(htmlline)];
int j=0;
if( currentline[j]=="<" )
{
while(currentline[j]!=">")
{
htmlfiletags[k][j]=currentline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
printf("\tcheck__3\n");
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
printf("\tcheck__4\n");
}
void copy_file(const char *from,const char *to)
{
FILE *fr;
FILE *t;
fr = fopen(from,"r");
t = fopen(to,"w");
char line[MAX_SIZE];
char row[MAX_SIZE];
while(fgets(line,sizeof(line),fr) != NULL)
{
sscanf(line,"%s",row);
fprintf(t,"%s\n",row);
}
fclose(fr);
fclose(t);
remove("tempfile.html");
}
void datumos()
{
time_t now = time(NULL);
struct tm *t = localtime(&now);
char date_time[30];
strftime( date_time, sizeof(date_time), "%x_%X", t );
FILE *htmlfile;
FILE *tempfile;
htmlfile = fopen("htmlfile.html","r");
tempfile = fopen("tempfile.html","w");
char line[MAX_SIZE];
//char datecomment[]="<!--#echo var=date -->";
while(fgets(line,sizeof(line),htmlfile) != NULL)
{
if( strcmp(line,"<!--#echo var="date" -->") == 0 )
{
char row[40];
strcpy(row,"<!--");
strcat(row, date_time);
strcat(row,"-->");
printf("%s",row);
fputs(row,tempfile);
}
else
{
fputs(line,tempfile);
}
}
fclose(htmlfile);
fclose(tempfile);
copy_file("tempfile.html","htmlfile.html");
}
it dies in this, in the inner for loop, in the if at the 200th check... i dont know why...
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
Thanks for all reply!!
G
Your code is very complicated, it has several issues.
Here's one:
for(j=0; j<sizeof(tags); ++j)
this will not do what I believe you expect; sizeof(tags) is not the array length of tags (which is declared as char tags[189][30];), it's the total size of the variable. So, this loop will go from 0 to 189 * 30 - 1, i.e. 5669, and thus index way out beyond the end of array.
Also, the idea to use sizeof here in any way is wrong, since the content of tags comes from a file and it thus impossible for the compiler to know. Remember that sizeof is evaluated at compile-time, for expressions like these.
You need to have a variable (e.g. size_t num_tags) that you increment for each line parsed from the tags file, and that you later use to iterate over tags.
Do not use regex, or some kind of string parsing, to parse HTML. Instead search the web, or this site, for a c library to parse html. Then check the parsed HTML file for the tags. This will ease the development a lot as you don't have to parse the files yourself.
i've fixed some things, but
- i still cant check the file's htmltags, dies at the same loop, i've fixed allocation of the tags array
- when in the htmlfile are 2 or more different comments and i'm replacing the comment the program replaces it with the sysdate, but the program copy the another comments badly, like =>
the code is now:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_SIZE 512
void menu();
void check();
void datumos();
int main(int argc,char *argv[])
{
menu();
return 0;
}
void menu()
{
char menu[MAX_SIZE];
while(1 < 2)
{
printf("\npress a button:\n\n");
printf("\tFile HTML check..............:c\n");
printf("\t<!--#echo var="date" -->...........:d\n");
printf("\tExit:\tCTRL + C\n");
scanf("%s",menu);
if( strcmp(menu,"c") == 0 )
{
check();
}
else if( strcmp(menu,"d") == 0 )
{
datumos();
}
}
}
void check()
{
FILE *htmlfile;
FILE *checkfile;
htmlfile = fopen("htmlfile.html","r");
checkfile = fopen("tags.txt","r");
char line[MAX_SIZE];
char htmlline[MAX_SIZE];
int i2=0;
printf("\tcheck__1\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
++i2;
}
char tags[i2][20];
int i=0;
printf("\tcheck__11\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
int j;
for(j=0; j<sizeof(line); ++j)
{
tags[i][j]=line[j];
}
++i;
}
printf("\tcheck__2\n");
int k=0; char htmlfiletags[MAX_SIZE][30];
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
char currentline[sizeof(htmlline)];
int j=0;
if( currentline[j]=="<" )
{
while(currentline[j]!=">")
{
htmlfiletags[k][j]=currentline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
printf("\tcheck__3\n");
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
//printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
// printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
printf("\tcheck__4\n");
}
void copy_file(const char *from,const char *to)
{
FILE *fr;
FILE *t;
fr = fopen(from,"r");
t = fopen(to,"w");
char line[MAX_SIZE];
char row[MAX_SIZE];
while(fgets(line,sizeof(line),fr) != NULL)
{
sscanf(line,"%s",row);
fprintf(t,"%s\n",row);
}
fclose(fr);
fclose(t);
remove("tempfile.html");
}
void datumos()
{
time_t now = time(NULL);
struct tm *t = localtime(&now);
char date_time[30];
strftime( date_time, sizeof(date_time), "%x_%X", t );
FILE *htmlfile;
FILE *tempfile;
htmlfile = fopen("htmlfile.html","r");
tempfile = fopen("tempfile.html","w");
char line[MAX_SIZE];
char* datecomment="<!--#echo var=\"date\" -->";
while(fgets(line,sizeof(line),htmlfile) != NULL)
{
int i3; int db=0;
for(i3=0; i3<strlen(datecomment); ++i3)
{
if(line[i3]==datecomment[i3])
{
++db;
}
}
if(db==strlen(datecomment))
{
char row[30];
strcpy(row,"<!--");
strcat(row, date_time);
strcat(row,"-->\n");
fputs(row,tempfile);
}
else
{
fputs(line,tempfile);
}
}
fclose(htmlfile);
fclose(tempfile);
copy_file("tempfile.html","htmlfile.html");
}
the currentline it's not necessary,and i've fixed the compares too
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
int j=0;
if( htmlline[j]=='<' )
{
while(htmlline[j]!='>')
{
htmlfiletags[k][j]=htmlline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
-in addition, the another problem to replace only the suitable comments, and dont hurt the different ones still dont work
"so it replaces
<!--#echo var="date" --> to the sysdate, it's ok, but when there are different comments like
<!--#include something -->, it wont be copied back well, in the htmlfile will be only <!--#include"
ideas?

Resources