Using recursion to find a 2D maze path. Seg Faulting. C - c

I am having trouble finishing this program. The assignment is to use recursion to find a path through a maze composed of X's and O's. The path one can go through is designated by the O's The maze is stored as a text file.
Here is a sample maze:
XOXXXXXX
XOXXXXXX
XOOOOXXX
XXXXOXXX
XXXXOOXX
XXXXXOXX
XXXXXOOO
XXXXXXXO
And here is my attached code. I am attatching all of my code, but I would not like to be told exactly how to do it, I am here to learn :-).I do believe my problem is with not accounting for the same O i just looked for, but im not 100% sure. Thanks!!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int find_path(char maze[8][8], int coorx, int coory);
int main(int argc, char *argv[])
{
char maze[8][8];
int i=0,j=0;
FILE *fp;
fp = fopen(argv[1], "r");
for(i=0;i<9;i++)
for(j=0;j<9;j++)
fscanf(fp,"%c",&maze[i][j]);
fclose(fp);
printf("%c", maze[2][3]);
return 0;
}
int find_path(char maze[8][8], int coorx, int coory)
{
//if((maze[coorx][coory]!= 'O') && (coorx >=0) && (coorx < 8) && (coory >=0) &&
//(coorx < 8)){
if(find_path(maze, coorx + 1, coory) == 'O'){
printf("(%d,%d)",coorx, coory);
}
else if(find_path(maze, coorx - 1, coory) == 'O'){
printf("(%d,%d)",coorx, coory);
}
else if(find_path(maze, coorx, coory + 1) == 'O'){
printf("(%d,%d)",coorx, coory);
}
else if(find_path(maze, coorx, coory - 1) == 'O'){
printf("(%d,%d)",coorx, coory);
}
return 0;
}

You have this declaration
char maze[8][8];
And loop like this
for(i=0;i<9;i++)
That is, you loop from zero to eight (inclusive) which is nine indexes. For an array of only eight entries.
This means you will write out of bounds of the arrays, leading to undefined behavior.
Either change your loop condition, or increase your array sizes.

find_path doesn't have a clear base case, since the if at the beginning is commented out. The very first thing it does, is call itself again with cell to the right. And the first thing that call does, is call itself again, with the cell to the right of that. There's nothing to stop it from just falling right off the end of the array, at which point it's just dumb luck you haven't caused missiles to launch somewhere.
Even if that weren't the case, there's nothing keeping it from getting stuck between a cell with a wall to the right, and the cell just to the left of it. You try to go right, but can't, so you go left. Next step, you can go right again, so you do. Repeat for all eternity (or at least til you eat up your stack).

Related

Why is my for loop increasing the size of my array in C?

I'm trying to make a binary number calculator in c and I'm running into issues of my for loops doubling the size of my second array and adding the first array onto the end. I'm really confused because I thought you couldn't increase the size after already declaring it. It is happening in my equation reading function as well but in this ones complement function it's a bit simpler to see. Any ideas of how to fix this?the codethe output
welcome to stack-overflow. From next time please use inline code editor to put your code instead of images. I have taken effort put your code in the answer itself to explain the problem. Please consider this as courtesy. Its very unusual to do it. But as you are a new member, I'm doing it.
// Cole carson's original code from image:
char * onescomp(char x[16], char y[16]){
int i;
for(i=0;i<=15;i++){
if(x[i] == '0'){
y[i] = '1';
continue;
}
else if(x[i] == '1'){
y[i] = '0';
continue;
}
}
return y;
}
int main()
{
char b3n[16]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char cb3n[16];
puts(b3n);
onescomp(b3n,cb3n);
puts(cb3n);
return 0;
}
Answer:
You don't need continue; in if-else blocks.
You need to add '\0' in the last cell of cb3n array. so puts() knows when string ends & stop printing.
so to quickly fix this issue you can create array with extra cell and assign all values as '\0'. so after copying fifteen 1's there will be '\0' in the end. I think in your case those extra zeros being printed might be garbage values. It looks like array is doubling but it isn't, its just printing values beyond allocated memory because '\0' has not been provided.
//Quick fix
int main()
{
char b3n[16]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char cb3n[17]={'\0'}; // <--- quick fix
puts(b3n);
onescomp(b3n,cb3n);
puts(cb3n);
return 0;
}

Infinite loop due to wrong condition in C

Hey guys i'm new to C and i'm trying to learn something by myself.
So here's the question: i have an infinite loop and i don't understand why.
I've already checked other topics but i didn't understand, actually.
Here's the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/**
* Auto-generated code below aims at helping you parse
* the standard input according to the problem statement.
**/
int main()
{
int n,i=0; // the number of temperatures to analyse
scanf("%d", &n); fgetc(stdin);
char temps[257]; // the n temperatures expressed as integers ranging from -273 to 5526
fgets(temps, 257, stdin); // the n temperatures expressed as integers ranging from -273 to 5526
int temp[257]={0};
char *pointer;
pointer= temps;
while(*pointer != NULL){
int i=0, sign=1;
if(*pointer == '-'){
sign=-1;
pointer++;
}
while(*pointer != 32) { //infinite loop!
if(*pointer >='0' && *pointer<='9'){
temp[i]= (temp[i] *10) + ((*pointer) -'0');
temp[i]= temp[i]*sign;
printf("try");
}
}
printf("%d\n", temp[i]); //verifying temps != 0
pointer++;
i++;
}
return 0;
}
I really don't understand why.
Anyway, the aim of the program is: "Write a program that prints the temperature closest to 0 among input data. If two numbers are equally close to zero, positive integer has to be considered closest to zero (for instance, if the temperatures are -5 and 5, then display 5)."
You may need it.
Thank you in advance.
In the loop:
while(*pointer != 32)
you never change pointer or *pointer within the loop body. So if this loop is entered once then it can never exit.
You probably meant to have a pointer++ somewhere, and perhaps the loop condition should actually be while(*pointer >='0' && *pointer<='9') (what if the string has some numbers, then a letter, then some numbers?)
However bear in mind that this loop will also have to check for end-of-string ('\0') and exit the outer loop correctly if it does hit that (instead of doing pointer++ and going past the terminator as you do in the case of the input being just -).
Ok, I actually understood. Thank you.
So now this is the loop
while(*pointer != 32 || *pointer != '\0') {
if(*pointer >='0' && *pointer<='9'){
temp[i]= (temp[i] *10) + ((*pointer) -'0');
temp[i]= temp[i]*sign;
pointer++;
}
}
Now it gives me values, but at a certain point, it becomes infinite.
The rest of the code is the same.
EDIT: i modified the loop condition with while(*pointer >='0' && *pointer<='9') and it's not infinite!
But doesn't work. There may be a logical mistake.
EDIT 2: i found it. i've initialized i=0 in the while loop and of course it kept updating the same temp[i].
Thank you again.

Printing all duplicate words from a file in C

What am I supposed to do in order to print only the duplicated words in a file. I'm a beginner in C.
Here's my code:
#include <stdio.h>
#define max 100
main(){
FILE *fpointer;
char ch[max],str[max][max];
int i = 0,j = 0,count = 0;
int a,b;
fpointer = fopen("1.txt","r");
if(fpointer == NULL){
printf("Error!");
return 0;
}
while(fscanf(fpointer,"%s",ch)!=EOF){
strcat(str[i++],ch);
strcat(str[i++]," ");
count++;
}
for(a=0;a<count*2;a=a+2){
for(b=0;b<count*2;b=b+2){
if(strcmp(str[a],str[b])==0){
printf("%s\n",str[b]);
}
}
}
fclose(fpointer);
return 0;
}
An example of input is "shine little star shine bright in the dark star"
and the output of this program is "shine shine little star star shine shine bright in the dark star star". Please help me to print
only duplicate words. Tnx
In your inner loop, instead of starting at the beginning of the list, start one element after the current one. That way you're not comparing an element against itself or comparing any two elements twice.
for(a=0;a<count*2;a=a+2){
for(b=a+2;b<count*2;b=b+2){ // b=a+2 instead of b=0
if(strcmp(str[a],str[b])==0){
printf("%s\n",str[b]);
}
}
}
Output:
shine
star
Since you wrote duplicate words, i am guessing the words in the file will be repeated twice only.
So you second nested for loop is starting from the beginning every time, and thats where the problem is. You have to make sure that the word already checked is not iterated over again. For that you can change your second for loop a little
for(a=0;a<count*2;a=a+2){
for(b=a+2;b<count*2;b=b+2){ //notice b=a+2
if(strcmp(str[a],str[b])==0){
printf("%s\n",str[b]);
}
}
}
Note
For cases when the words are repeating more then twice, my suggestion would be to use some hashing technique to store if a word has already occurred or not. And then compare and print accordingly.
You have a couple of problems here.
Go through and write some comments. For example, put these where they belong:
// Open the file
// Read in the strings
// Compare the strings
If you do this you will notice you have some problems. For instance, what is this line for?
strcat(str[i++]," ");
It's not reading in a string. So what is it doing?
In your final loop, you want to compare each string with all the others. So obviously, you start with the first string, and you compare it to all the others:
for (a=1; a<count; a++)
if(strcmp(str[0],str[a])==0)
{
printf("%s\n",str[0]);
break;
}
Now we can compare the first string with each following string and print it out if it is duplicated. The "break" is there so we only print it once.
But this only compares the first string with the others. How do we compare all of them? Another loop, of course.
// Compare each string against all the ones after it
for (target=0; target<count; target++)
for (a=target+1; a<count; a++)
// If the strings match AND they are not both null
// (why print out copies of null strings? - nobody wants that)
if(strcmp(str[target],str[a])==0) && strlen(str[a])
{
// Print it
printf("%s\n",str[target]);
// Why is this here?
strcpy(str[a],"");
for (copies=a+1; copies<count; copies++)
if(strcmp(str[copies],str[target])==0)
strcpy(str[copies],"");
// We got a match, stop checking for this string
break;
}
See how we've got one big loop that steps through each string, and a smaller loop that steps through all the remaining strings (no point in stepping through the ones we already looked at).
Now a question for you: why is "strcpy(str[a],"") and the next for loop in there? What purpose do they serve?
This is one way to do it. Please enable warnings - you left out a library header. I've also checked array limits. You need to find a better way to limit the string input too, than just guess a large array size.
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // included header
#define MAX 100
int main(void){ // correct function
FILE *fpointer;
int reported [MAX];
char ch[MAX], str[MAX][MAX];
int index = 0, a;
fpointer = fopen("1.txt","r");
if(fpointer == NULL){
printf("Error!");
return 0;
}
while(fscanf(fpointer,"%s",ch) == 1){ // testing for 1 item read
for(a=0; a<index; a++){
if(strcmp(ch, str[a])==0){
if (reported[a] == 0) // don't report twice
printf("%s ",ch);
reported[a]++;
break;
}
}
if(a >= index) { // check if loop completed
if (index >= MAX) { // check if array is full
printf("\nToo many words read\n");
exit(1);
}
strcpy(str[index], ch); // word was not found
reported[index] = 0;
index++; // keep tabs on array length
}
}
printf("\n",ch);
fclose(fpointer);
return 0;
}
Program output:
shine star
One issue is that you are storing every word, regardless of whether it has already been seen:
while(fscanf(fpointer,"%s",ch)!=EOF){
strcat(str[i++],ch);
strcat(str[i++]," "); // ??? what is this for
count++;
}
Ideally, you'd only like to store each word once, and maintain a count of how often that word appears in the file:
while ( fscanf( fpointer, "%s", ch ) != EOF ) // whitespace is your friend, use it
{
if ( ch_is_not_already_in_str )
{
strcpy( str[count++], ch );
}
else
{
update_count_for_that_string;
}
}
Then at the end, you just loop through ch and print each string that has a count greater than 1.
for ( i = 0; i < count; i++ )
{
if ( str[i]_occurs_more_than_once )
printf( "%s ", str[i] );
}
The bits you need to figure out are ch_is_not_already_in_str, update_count_for_that_string, and str[i]_occurs_more_than_once. How would you go about searching your str array for an occurence of the string in ch? How would you maintain a counter for each string?

My program is locking up and doesn't seem to do what it's supposed to. What have I done wrong?

I'm a newbie to C programming and I'm up to learning about strings and arrays. My latest challenge is to read in a string, calculate the frequency of each letter and output these including non-letters.
I've written the program but it either locks up or just stops. I can't get it to start the count. Where have I gone wrong?
NB: My lecturer has some particular views on syntax that other people don't necessarily share. I'm going to stick with the syntax that's going to keep my lecturer happy so please don't pick on the "return (0);" at the end of the main function.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
const int COUNT = 27;
const int STRSIZE = 100;
counter[c]++;
c++;
}
else
if((letterfreq[i] < 'a') || (letterfreq[i] > 'z'))
{
counter[26]++;
}
}
}
return;
}
void printFreq(int counter[], int COUNT)
{
int c;
in the string.\n", counter[26]);
return;
}
char promptReset(char reset)
{
printf("Would you like to calculate the letter frequency of another string? (Y/N)\n");
scanf("%c%*c", &reset);
tolower(reset);
return(reset);
}
int main()
{
In your code,
tolower(letterfreq[STRSIZE]);
is overruning allocated memory, which in turn invokes undefined behaviour. Remember, C array index is 0 based.
That said,
I don't see the point of the whole statement here. Maybe you'd want to have a look at the man page of tolower(http://linux.die.net/man/3/tolower) one again.
There is no need to pass COUNT, STRSIZE as arguments to functions.

reversing a string of integers user enters (C)

What I want to do is reverse a string of numbers that the user enters. what happens is it compiles and runs till i hit enter after the scanf. then I get some Microsoft runtime error... what's going wrong???
NOTE: this is homework, but i've got the logic figured out. what baffles me is this error.
#include <stdio.h>
int main()
{
unsigned int giveStr = 0;
char* charIt;
printf("Enter a number to be reversed.\t");
scanf("%d", &giveStr);
fflush(stdin);
sprintf(charIt, "%d", giveStr);
revStr(giveStr);
getchar();
return 0;
}
revStr(unsigned int n)
{
char buffer[100];
int uselessvar, counter = 0;
for (; n > 0;)
{
uselessvar = sprintf(&buffer[counter], "%d", n);
counter++;
}
for (counter = 0; counter > 0;)
{
printf("%c", buffer[counter]);
counter--;
}
return 0;
}
EDIT: flushing stdin for newlines :/ and also image here just not with that program. with mine.
You are trying to access memory which is not allocated in:
sprintf(charIt, "%d", giveStr);
Change char* charIt; to char charIt[50]; and all should be well (well, at least the segmentation fault part)
Also... pass charIt to revStr, as charIt contains the string with our number.
Then, a simple for loop in revStr will do the trick (what was the purpose of the second one, anyway?)
void revStr(char *giveStr)
{
int counter;
for (counter = strlen(giveStr)-1; counter >= 0; counter--)
{
printf("%c", giveStr[counter]);
}
printf("\n");
}
This will print each char our char representation has from the last one till the first one. You should read more on for loops.
For your home work problem, if you have the K&R book, turn to section 3.5 and read it thoroughly.
Note the functions reverse() and itoa(). They should give you a pretty good idea on how to solve your problem.
How does your program get out of the for (; n > 0;) loop? Won't counter simply increase until you get a bus error?
ED:
Respectfully, I think the claim that "i've got the logic figured out" is a little optimistic. :^) Doubtless someone will post the way it should have been done
by the time I'm done writing this, but it's probably worth drawing attention to what went wrong (aside from the memory allocation problems noted elsewhere):
Your first loop, "for (; n > 0;)", is strange because you're printing the entire number n into the buffer at counter. So why would you need to do this more than once? If you were selecting individual digits you might, but you're not, and obviously you know how to do this because you already used "sprintf(charIt, "%d", giveStr);". [Aside: giveStr isn't a great name for an unsigned integer variable!]
Your second loop also has strange conditions: you set counter to 0, set the condition that counter > 0, and then decrease counter inside. This obviously isn't going to loop over the characters in the way you want. Assuming you thought the first loop was character-by-character, then maybe you were thinking to loop down from counter-1 to 0?

Resources