C : strchr pointer value doesn't change - c

I'm trying to recursively search for a substring in a string using C program. I wrote the following piece of code. The issue I'm facing is that, the ptr value, though it prints the correct value(using puts in the beginning of while), while usage its value is not changed! It uses the previous ptr value. I found this out using gdb. I couldn't figure out the cause of this. Kindly guide me to solve this issue. Thanks in advance.
void main()
{
char buf[10]="hello",*ptr;
char findc[10]="lo";
int len,i,lenf,k,l,flag=0;
lenf=strlen(findc);
l=0,k=1;
ptr=strchr(buf,findc[l]);
while(ptr!=NULL)
{
puts(ptr);
l++;
for(i=l;i<(lenf);i++,k++)
{
if(ptr[k] != findc[i])
{
flag=1;
break;
}
}
if(flag==1)
{
l=0;k=1;
ptr=strchr((ptr+1),findc[l]);
if(ptr==NULL)
{
puts("String not found");
break;
}
}
else
{
puts("String found");
break;
}
}
}

It was a very simple mistake!
We'll have to reset the flag variable in the beginning of the while loop. This would solve the issue.
Thanks!

Related

how to change the program to do the same task without the program crashing?

I have an assignment to produce a program that will compare students answer to the answer key, and display the incorrect answers. The program then produces a report of the students incorrect answers and his final grade. The Program must use arrays and functions.
Currently I am trying to code two functions one to read the students answer file and store it in an array and the other to read answer key file and store it in another array. Then the functions will return both arrays to the main function later to be sent to another function to compare their contents(not yet done).
My problem with this code after pressing F11 to compile and run, i get a blank execution screen and a notification saying that the program has stopped working.
If my code contains a mistake or my approach is incorrect please tell me how to fix it.
note: this is my first semester learning C programming.
Thank you.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
//Modules
char* readstudent()
{
FILE*s_ans;
int i,j;
static char arrs[20];
s_ans=fopen("trial2.txt","r");
if (s_ans == NULL)//check if file can be opened
{
printf("error student");
}
while(!feof(s_ans))
{
for(j=0;j<20;j++)
{
fscanf(s_ans,"%s",arrs[j]);
}
}
printf("ReadStudent\n");
for(i=0;i<20;i++)
{
printf("%d\t %s\n",i+1,arrs[i]);
}
return arrs;
}
char* readcorrect()
{
FILE*c_ans;
int x,i;
static char arrc[20];
c_ans=fopen("CorrectAnswers.txt","r");
if (c_ans == NULL)//check if file can be opened
{
printf("error correct");
}
while(!feof(c_ans))
{
for(x=0;x<20;x++)
{
fscanf(c_ans,"%s",arrc[x]);
}
}
printf("ReadCorrect\n");
for(i=0;i<20;i++)
{
printf("%d\t %s\n",i+1,arrc[i]);
}
return arrc;
}
//Main
int main()
{
int i,j,n,x;
char* as_ans=readstudent();
char* ac_ans=readcorrect();
printf("Main");
for(i=0;i<20;i++)
{
printf("%s",as_ans[i]);
}
return 0;
}

Understanding the logic behind a piece of C code

I would love if you guys could explain to me why the following piece of recursive code doesn't print the word 'test'. Thanks in advance.
void drawTetriminosEachPosition(int **tetriminos, char **dBoard, int **tBoard, int i){
char c;
char **dBoard2;
if(tetriminos[i] == '\0')
{
return;
}
else
{
dBoard2 = dBoard;
DrawTetrimino(tBoard, tetriminos[i], dBoard, i+65);
}
i++;
return (drawTetriminosEachPosition(tetriminos,dBoard,tBoard,i));
ft_putstr("test");
if(checkChar(tBoard,tetriminos[i]))
{
dBoard = dBoard2;
return (drawTetriminosEachPosition(tetriminos,dBoard,tBoard,i));
}
}
Statements after a return are never executed. Since the first
return (drawTetriminosEachPosition(tetriminos,dBoard,tBoard,i));
does not depend on any condition, the following code is not executed.
When control reaches return ... it simply returns and next lines are not executed. Maybe you missed some logic in between?
As of now you can delete this part it doesn't matter
ft_putstr("test");
if(checkChar(tBoard,tetriminos[i]))
{
dBoard = dBoard2;
return (drawTetriminosEachPosition(tetriminos,dBoard,tBoard,i));
}

Mysterious change of value in pointer vector

As homework I have to implement a function that receives two vectors of pointers. It should compare the values contained in the memory address pointed by these pointers and return TRUE or FALSE if they are all the same or not.
For this I have created this function:
tBoolean comparePointerVector(int *v1[], int *v2[]) {
int i;
tBoolean status = TRUE;
for (i=0;i<MAX_DELIVERIES;i++) {
if(*v1[i]!=*v2[i]) {
status = FALSE;
break;
}
}
return status;
}
The method compiles fine but always crashes in the first iteration. Investigating the problem I have found a very strange phenomena. Adding the next code before entering the for loop, the printed results for both lines are different, which is very surprising for me:
printf("value %d\n ",*v1[0]);
printf("value %d\n ",*v1[0]);
The first line prints correctly the value pointed by v1[0], but the second line prints the memory address. How is this possible that the they don't print the same?
Besides this why this code seems to break my program?
*v1[i]!=*v2[i]
I ask here in the same question because I think both questions are related.
EDIT:
Definition of MAX_DELIVERIES in a file called data.h
#define MAX_DELIVERIES 50
Calling the function:
tBoolean pd_equals(tProductDeliveries pd1, tProductDeliveries pd2){
//For maintenability and better understading this method contains several 'return' statements.
if(pd1.poductID!=pd2.poductID) {
return FALSE;
} else if(pd1.totalPurchases!=pd2.totalPurchases) {
return FALSE;
} else if(pd1.totalSales!=pd2.totalSales) {
return FALSE;
} else if(pd1.total!=pd2.total) {
return FALSE;
} else if(comparePointerVector(pd1.sales, pd2.sales) != TRUE) {
return FALSE;
} else if(comparePointerVector(pd1.purchases, pd2.purchases) != TRUE) {
return FALSE;
}
return TRUE;
}
Calling the pd_equals method:
pd_getProductDeliveries(deliveries, 123, &pd1);
if(pd_equals(pd1, pd1)==TRUE) {
printf("\n\t-> OK\n");
passedTest[0]++;
} else {
printf("\n\t-> FAIL.\n");
}
Thanks everybody for your answers. I got it fixed but now I am even more puzzled.
I just have removed the system("PAUSE"); I had between the two printf and now both print exactly the same. I am sorry I didn't post it in my code but I thought it was totally irrelevant.
Now my next question would be: What in the world is the system("PAUSE") doing that messes up the memory?
I think the issue is caused by the comparison if(*v1[i]!=*v2[i]). It must be
v1[i] != v2[i] or *(v1+i) != *(v2+i)

Allocation to Pointers

I work with char ****pCourses
int Courses(char ****pCourses, int ****pGrades, int **pCount, int *count)
{
char *buffer=NULL;
char letter;
int j=0, i;
int size=20;
int countCourse=0, sumCourses=0;
buffer=(char *)malloc(size*sizeof(char));
do
{
scanf("%c",&letter);
}while(letter==32);
while(letter!=10)
{
while(letter!=',')
{
//in case we need to expend the buffer
if(j>size)
{
size*=2;
buffer=(char *)realloc(buffer,size*sizeof(char));
}
buffer[j]=letter;
j++;
//The new letter from the name of course
scanf("%c",&letter);
}
//The end of the name of course
buffer[j]='\0';
j=0;
if(countCourse==0)
{
*pCount=(int *)realloc(*pCount, ((*count)+1)*sizeof(int));
(*pCount)[*count]=1;
}
else
(*pCount)[*count]++;
//Add the course's name to the system
*pCourses=(char ***)realloc(*pCourses, ((*count)+1)*sizeof(char ***));
(*pCourses)[*count]=(char **)realloc((*pCourses)[*count],(countCourse+1)*sizeof(char *));
((*pCourses)[*count])[countCourse]=(char *)malloc(strlen(buffer)+1);
strcpy(((*pCourses)[*count])[countCourse], buffer);
countCourse++;
scanf("%c",&letter);
}
free(buffer);
return 0;
}
while running I get a problem because of the next line:
(*pCourses)[*count]=(char **)realloc((*pCourses)[*count],(countCourse+1)*sizeof(char *));
that leads me to this part (from dbgheap.c):
{
while (nSize--)
{
if (*pb++ != bCheck)
{
return FALSE;
}
}
return TRUE;
}
does someone know what it means or why does this happen?
I think you've already been told what the problem is. All the alloc-type functions can fail and you should test for that and ideally write code that is robust enough to code with a failure.
Note that repeatedly using realloc() is not a good idea. If you expect to have to repeatedly add ( or remove ) data then you should be using a different structure, like a linked list or tree, which are designed to allow adding and removing data on the fly.

Longest Common Subsequence-Segmentation fault

I have to write a program to determine the longest common sub sequence.
Input:
The first argument will be a file that contains two strings per line, semicolon delimited. You can assume that there is only one unique subsequence per test case. e.g.
XMJYAUZ;MZJAWXU
Output:
The longest common subsequence. Ensure that there are no trailing empty spaces on each line you print. e.g.
MJAU
I am using Dev C++ .. And it is compiling Fine!...But this question is a programming challenge and when i submit my answer it's showing me a segmentation fault!
I have written the following code and i am getting a Segmentation Fault where am i wrong?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char str1[100],str2[100];
int len1;
int len2;
void printLCS(char b[len1][len2],char str1[],int i,int j)
{
if(i==0 || j==0)
return;
if(b[i][j]=='c')
{
printLCS(b,str1,i-1,j-1);
printf("%c",str1[i-1]);
}
else if(b[i][j]=='l')
printLCS(b,str1,i,j-1);
else
printLCS(b,str1,i-1,j);
}
void Seq(char str1[],char str2[])
{
int i,j;
len1=strlen(str1);
len2=strlen(str2);
int LCS[len1+1][len2+1];
char b[len1][len2];
for(i=0;i<=len1;i++)
{
LCS[i][0]=0;
}
for(j=0;j<=len2;j++)
{
LCS[0][j]=0;
}
for(i=1;i<=len1;i++)
{
for(j=1;j<=len2;j++)
{
if(str1[i-1]==str2[j-1])
{
LCS[i][j]=1+LCS[i-1][j-1];
b[i][j]='c';
}
else if(LCS[i-1][j]>=LCS[i][j-1])
{
LCS[i][j]=LCS[i-1][j];
b[i][j]='u';
}
else
{
LCS[i][j]=LCS[i][j-1];
b[i][j]='l';
}
}
}
printLCS(b,str1,len1,len2);
}
int main(int argc,char *argv[])
{
if(argc!=2)
{
printf("Invalid Number of Arguments:\n");
exit(0);
}
FILE *fp;
fp=fopen(argv[1],"r");
if(fp==NULL)
{
printf("File can't be opened:\n");
exit(0);
}
char c;
c=fgetc(fp);
while(c!=EOF)
{
int k=0;
if(c=='\n')
c=fgetc(fp);
while(c!=';')
{
str1[k]=c;
k++;
c=fgetc(fp);
}
str1[k]='\0';
c=fgetc(fp);
k=0;
while(c!=EOF && c!='\n')
{
str2[k]=c;
k++;
c=fgetc(fp);
}
str2[k]='\0';
Seq(str1,str2);
printf("\n");
if(c==EOF)
{
break;
}
else
c=fgetc(fp);
}
return 0;
}
I dont know system of this site but;
i compiled with no error,
and result was true.
You didnt close file. Maybe memory leak etc. didnt allowed by site.
And, dont use global variables, unless you dont know another solution
this usage is very very bad! ISO C90 forbids this, anyway
int len1;
int len2;
void printLCS(char b[len1][len2]...
good luck.
If you've got access to a Mac or Linux system, there's a fantastic tool called valgrind which can help you track down these kinds of errors: basically it runs your program in a virtual machine and monitors what it reads and writes to memory.
Whilst I can't compile your code, I'm pretty suspicious about this for loop:
for(i=1;i<=len1;i++)
{
for(j=1;j<=len2;j++)
{
if(str1[i-1]==str2[j-1])
{
LCS[i][j]=1+LCS[i-1][j-1];
b[i][j]='c';
}
else if(LCS[i-1][j]>=LCS[i][j-1])
{
LCS[i][j]=LCS[i-1][j];
b[i][j]='u';
}
else
{
LCS[i][j]=LCS[i][j-1];
b[i][j]='l';
}
}
}
Arrays in C and C++ start at 0, so the maximum offset you're interested in is probably strlen - 1. Try changing your for loops to
for(i=1;i<len1;i++)
{
for(j=1;j<len2;j++)
{
...
}
}

Resources