Segmentation Fault when looping through 2D Char Array, Wordsearch - c

My assignment is to create a wordsearch that looks through words in a list (called 'list' in the code) and finds it in a 2D grid (called 'arr'). If a word is found I need to make the words lowercase in the grid and print it out. I need to look in 5 directions, r2l, l2r, t2b, tl2br, and tr2bl. I am able to run the Right to Left comparison and am able to print out the grid with the found words in lowercase. However I get a seg fault every time I attempt to compare in any other direction. Any help?
Puzzle.txt file: https://ucmerced.box.com/s/twkdxega6d34bkou3mpy0xtm901grlx3
states.txt file: https://ucmerced.box.com/s/4zi7etq3wab3y81m64kx6naaiy2bttea
#include <string.h>
void printPuzzle(char** arr, int n);
void searchPuzzle(char** arr, int n, char** list, int listSize);
void lowerCaseL2R(char** arr, int y, int x, int lengthOfWord);
void lowerCaseT2B(char** arr, int y, int x, int lengthOfWord);
int searchAll(char** arr, int k, int l, int ii, char** list, int lengthOfWord);
char upperCase(char letter);
int main(int argc, char **argv) {
int bSize = 15;
if (argc != 2) {
fprintf(stderr, "Usage: %s <puzzle file name>\n", argv[0]);
return 2;
}
int i, j;
FILE *fptr;
char **block = (char**)malloc(bSize * sizeof(char*));
char **words = (char**)malloc(50 * sizeof(char*));
// Open file for reading puzzle
fptr = fopen(argv[1], "r");
if (fptr == NULL) {
printf("Cannot Open Puzzle File!\n");
return 0;
}
// Read puzzle block into 2D arrays
for(i=0; i<bSize; i++){
*(block+i) = (char*)malloc(bSize * sizeof(char));
fscanf(fptr, "%c %c %c %c %c %c %c %c %c %c %c %c %c %c %c\n", *(block+i), *(block+i)+1, *(block+i)+2, *(block+i)+3, *(block+i)+4, *(block+i)+5, *(block+i)+6, *(block+i)+7, *(block+i)+8, *(block+i)+9, *(block+i)+10, *(block+i)+11, *(block+i)+12, *(block+i)+13, *(block+i)+14 );
}
fclose(fptr);
// Open file for reading word list
fptr = fopen("states.txt", "r");
if (fptr == NULL) {
printf("Cannot Open Words File!\n");
return 0;
}
// Save words into arrays
for(i=0; i<50; i++){
*(words+i) = (char*)malloc(20 * sizeof(char));
fgets(*(words+i), 20, fptr);
}
// Remove newline characters from each word (except for the last word)
for(i=0; i<49; i++){
*(*(words+i) + strlen(*(words+i))-2) = '\0';
}
// Print out word list
printf("Printing list of words:\n");
for(i=0; i<50; i++){
printf("%s\n", *(words + i));
}
printf("\n");
// Print out original puzzle grid
printf("Printing puzzle before search:\n");
printPuzzle(block, bSize);
printf("\n");
// Call searchPuzzle to find all words in the puzzle
searchPuzzle(block, bSize, words, 50);
printf("\n");
// Print out final puzzle grid with found words in lower case
printf("Printing puzzle after search:\n");
printPuzzle(block, bSize);
printf("\n");
return 0;
}
void printPuzzle(char** arr, int n){
int i, j;
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
printf("%c", *(*(arr + i) + j));
if(j == (n - 1)){
printf("\n");
}
}
}
}
void searchPuzzle(char** arr, int n, char** list, int listSize){
//arr is puzzle block (wordsearch), n is 15, list is a 2D array of words we are searching for (states), listSize is 50;
int i, j, k, l, m, lengthOfWord = 0, found = 0;
for(i = 0; i < listSize; i++){
for(j = 0; (*(*(list + i) + j) != '\0'); j++){
//number of iterations is equivalent to length of word;
}
lengthOfWord = j;
for(k = 0; k < 15; k++){
for(l = 0; l < 15; l++){
if(*(*(arr + k) + l) == *(*(list + i))) {
found = searchAll(arr, k, l, i, list, lengthOfWord);
if(found == 1){
lowerCaseL2R(arr, k, l, lengthOfWord);
}
if(found == 2){
lowerCaseT2B(arr, k, l, lengthOfWord);
}
}
}
}
}
}
int searchAll(char** arr, int k, int l, int ii, char** list, int lengthOfWord){
int dir1, i1, i2, count1 = 0, count2 = 0;
for(dir1 = 0; dir1 < lengthOfWord; dir1++){
if((*(arr + k) + (l + dir1))){
if(*(*(arr + k) + (l + dir1)) == (upperCase(*(*(list + ii) + dir1)))){
count1++;
}
if(count1 == lengthOfWord){
printf("Found: ");
for(i1 = 0; i1 < lengthOfWord; i1++){
printf("%c", *(*(list + ii) + i1));
}
printf("\n");
return 1;
}
}
}
/*(for(dir2 = 0; dir2 < lengthOfWord; dir2++){
if((*(arr + k + dir2) + l)){ // if(*(*(arr + k + dir2) + l)) != '\0' did NOT work
if(*(*(arr + k + dir2) + l) == (upperCase(*(*(list + ii) + dir2)))){
count2++;
}
if(count2 == lengthOfWord){
printf("Found: ");
for(i2 = 0; i2 < lengthOfWord; i2++){
printf("%c", *(*(list + ii) + i2));
}
printf("\n");
return 2;
}
}
}*/
return 0;
}
char upperCase(char letter){
if(letter >= 'a' && letter <= 'z'){
letter = letter + ('A' - 'a');
}
return letter;
}
void lowerCaseL2R(char** arr, int y, int x, int lengthOfWord){
for(int i = 0; i < lengthOfWord; i++){
*(*(arr + y) + (x + i)) = *(*(arr + y) + (x + i)) + ('a' - 'A');
}
}

Related

How to make a program that scrambles the order of the words in a sentence from a file

I have a file with say 4 sentences, I know that there are 4 because each sentence has '.' at the end.
What I did was read from the file given and paste each sentence in a 2 dimensional array like so:
char sentence[0][200] = "Hello how are you."
char sentence [1][200] = "I'm good thanks. etc.
Here is the code for this:
int main()
{
char sentence[RSIZ][LSIZ];
char fname[20] = "t.txt";
FILE *fptr = NULL;
int i = 0;
int tot = 0;
char c;
int nrsentences = 0;
printf("\n\n Read the file and store the lines into an array :\n");
printf("------------------------------------------------------\n");
fptr = fopen(fname, "r");
// Check if file exists
if (fptr == NULL)
{
printf("Cant open the file %s", fname);
return 0;
}
// Sentences counter from file
for (c = getc(fptr); c != EOF; c = getc(fptr))
if (c == '.') // Increases if found '.'
nrsentences = nrsentences + 1;
fptr = fopen(fname, "r");
for (i=0; i<nrsentences; i++)
fgets(sentence[i], 200, fptr);
Then I would separate the this array in to words with this code:
(still in main(){})
char newString[10][30];
int j,ctr;
j=0; ctr=0;
for (int k = 0; k < nrsentences; k++) {
for(i=0;i<=(strlen(frases[k]));i++)
{
// if space or NULL found, assign NULL into newString[ctr]
if(sentence[k][i]==' '|| sentence[k][i]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=sentence[k][i];
j++;
}
}
}
printf("\n Strings or words after split by space are :\n");
for(i=0;i < ctr;i++)
printf(" %s ",newString[i]);
Then here is the problem (I think), the part of the scrambling code.
This works like this:
I give the code: the sentences and the inedex.
by default it is like this
index-> 0 1 2 3
sentence-> Hello how are you
but with this code it converts to this:
index-> 3 2 0 1
sentence-> you are Hello how
int index[] = {2,3,5,1,0,4,7,6}; //here I have a function that generates the random list(which I dont know yet how to make it work here
int n = nrsentences;
randomize(newString, index, n, nrsentences);
printf("Reordered array is: \n");
for (int i=0; i<n; i++)
printf ("%s ", newString[i]);
return 0;
}
Here is the randomize() function
void randomize(char* arr[], int index[], int n, int nrsentences)
{
printf("%d", n);
char* temp[n];
// arr[i] should be present at index[i] index
//for (int k = 0; k < nrsentences; k++){
for (int i=0; i<n; i++)
temp[index[i]] = arr[i];
// Copy temp[] to arr[]
for (int i=0; i<n; i++)
{
arr[i] = temp[i];
index[i] = i;
}
//}
}
And here is the index randomizer, which I dont know yet (didnt try) how to add it to the main, or randomize function.
int *random_number(int words)
{
int array[25];
int x, p, count;
int i=0;
srand(time(NULL));
while(i< words){
int r=rand()% words +1;
for (x = 0; x < i; x++)
{
if(array[x]==r){
break;
}
}
if(x==i){
array[i++]=r;
}
}
for(p=0;p<words;p++){
printf("%d ", array[p]);
}
return array;
}
or
int array[25];
int words = 5;
int x, p, count;
int i=0;
srand(time(NULL));
while(i< words){
int r=rand()% words +1;
for (x = 0; x < i; x++)
{
if(array[x]==r){
break;
}
}
if(x==i){
array[i++]=r;
}
}
for(p=0;p<words;p++){
printf("%d ", array[p]);

Why does i never get past 1?

I am trying to create a program to solve a wordsearch from a 2D array using only pointers. In my primary function for doing the actual search for the words I have a while loop that is supposed to keep going as long as i doesn't exceed the length of the word and as long as the letters from the word correspond to the letters on the grid. After finding the word it should make the letters on the grid lowercase and print out that it found the word. Here is my entire program right now.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void printPuzzle(char** arr, int n);
void searchPuzzle(char** arr, int n, char** list, int listSize);
void searchWord(int j, int k, int gridsize, char** arr, char** list, int listPos);
int main(int argc, char **argv) {
int bSize = 15;
if (argc != 2) {
fprintf(stderr, "Usage: %s <puzzle file name>\n", argv[0]);
return 2;
}
int i, j;
FILE *fptr;
char **block = (char**)malloc(bSize * sizeof(char*));
char **words = (char**)malloc(50 * sizeof(char*));
fptr = fopen(argv[1], "r");
if (fptr == NULL) {
printf("Cannot Open Puzzle File!\n");
return 0;
}
for(i=0; i<bSize; i++){
*(block+i) = (char*)malloc(bSize * sizeof(char));
fscanf(fptr, "%c %c %c %c %c %c %c %c %c %c %c %c %c %c %c\n", *(block+i), *(block+i)+1, *(block+i)+2, *(block+i)+3, *(block+i)+4, *(block+i)+5, *(block+i)+6, *(block+i)+7, *(block+i)+8, *(block+i)+9, *(block+i)+10, *(block+i)+11, *(block+i)+12, *(block+i)+13, *(block+i)+14 );
}
fclose(fptr);
fptr = fopen("states.txt", "r");
if (fptr == NULL) {
printf("Cannot Open Words File!\n");
return 0;
}
for(i=0; i<50; i++){
*(words+i) = (char*)malloc(20 * sizeof(char));
fgets(*(words+i), 20, fptr);
}
for(i=0; i<49; i++){
*(*(words+i) + strlen(*(words+i))-2) = '\0';
}
printf("Printing list of words:\n");
for(i=0; i<50; i++){
printf("%s\n", *(words + i));
}
printf("\n");
printf("Printing puzzle before search:\n");
printPuzzle(block, bSize);
printf("\n");
searchPuzzle(block, bSize, words, 50);
printf("\n");
printf("Printing puzzle after search:\n");
printPuzzle(block, bSize);
printf("\n");
return 0;
}
void printPuzzle(char** arr, int n){
for(int i = 0; i < n; i++){
printf("\n");
for(int j = 0; j < 15; j++){
printf("%c ", *(*(arr+i)+j));
}
}
}
void searchPuzzle(char** arr, int n, char** list, int listSize){
for(int i = 0; i < listSize; i++){
for(int j = 0; j < 15; j++){
for(int k = 0; k < 15; k++){
searchWord(j, k, 15, arr, list, i);
}
}
}
}
void searchWord(int j, int k, int gridsize, char** arr, char** list, int listPos){
int wordlength = strlen(*(list+listPos));
if(j+wordlength <= gridsize){ //Horizontal
int i = 0;
while(i < wordlength && *(*(arr+(j+i))+k) == *(*(list+listPos)+i)){
i++;
}
if(i == wordlength){
while(i > 0 && *(*(arr+(j+i))+k) == *(*(list+listPos)+i)){
*(*(arr+(j+i))+k) = tolower(*(*(arr+(j+i))+k));
i--;
}
printf("Word found: ");
for(i = 0; i < wordlength; i++)
printf("%c", *(*(list+listPos)+i));
}
}
if(k+wordlength <= gridsize){ //Vertical
int i = 0;
while(i < wordlength && *(*(arr+j)+(k+i)) == *(*(list+listPos)+i)){
i++;
}
if(i == wordlength){
while(i > 0 && *(*(arr+j)+(k+i)) == *(*(list+listPos)+i)){
*(*(arr+(j+i))+k) = tolower(*(*(arr+(j+i))+k));
i--;
}
printf("Word found: ");
for(i = 0; i < wordlength; i++){
printf("%c", *(*(list+listPos)+i));
}
}
}
if(j+wordlength <= gridsize && k+wordlength <= gridsize){ //Diagonal
int i = 0;
while(i < wordlength && *(*(arr+(j+i))+k) == *(*(list+listPos)+i)){
i++;
}
if(i == wordlength){
while(i > 0 && *(*(arr+(j+i))+(k+i)) == *(*(list+listPos)+i)){
*(*(arr+(j+i))+(k+i)) = tolower(*(*(arr+(j+i))+(k+i)));
i--;
}
printf("Word found: ");
for(i = 0; i < wordlength; i++)
printf("%c", *(*(list+listPos)+i));
}
}
}
This is the part I believe there is a problem with.
while(i < wordlength && *(*(arr+(j+i))+k) == *(*(list+listPos)+i)){
i++;
}
If I print out the decimal value of i after this while loop it should at some point approach the length of one of the words as I know some words are horizontal, however every time it loops through and prints the value of i it never exceeds 1 which means the while loop never runs more than once which is impossible with the wordsearch files I am using to test this. What is causing this to happen? It is also 0 or 1 for every other direction when I try, the example above was just the while loop from the horizontal search.
There may also be a problem with the function searchPuzzle and the amount it loops through. However, I think that may be just my imagination.
Additional Info: The grid is 15x15 and there are 50 words in the list.
I think that you might need to declare Wordsearch again after the && -
while(i < wordlength && wordlength *(*(arr+(j+i))+k) == *(*(list+listPos)+i)){
i++;
}

How do I fix this wordsearch program?

I am creating a program without the use of arrays, only pointers, that solves wordsearches. The logic behind my program seems solid, but I am not getting any result when I run it. After finding the word the program is supposed to make the word in the 2D array become lowercase and print out the found word.
The problem I am seeing is that when it prints out the array again after the search is supposed to happen, it doesn't have the lowercase characters and it also isn't printing out the words that are found. I can't figure out why this is happening.
This is my program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
int bSize = 15;
if (argc != 2) {
fprintf(stderr, "Usage: %s <puzzle file name>\n", argv[0]);
return 2;
}
int i, j;
FILE *fptr;
char **block = (char**)malloc(bSize * sizeof(char*));
char **words = (char**)malloc(50 * sizeof(char*));
fptr = fopen(argv[1], "r");
if (fptr == NULL) {
printf("Cannot Open Puzzle File!\n");
return 0;
}
for(i=0; i<bSize; i++){
*(block+i) = (char*)malloc(bSize * sizeof(char));
fscanf(fptr, "%c %c %c %c %c %c %c %c %c %c %c %c %c %c %c\n", *(block+i), *(block+i)+1, *(block+i)+2, *(block+i)+3, *(block+i)+4, *(block+i)+5, *(block+i)+6, *(block+i)+7, *(block+i)+8, *(block+i)+9, *(block+i)+10, *(block+i)+11, *(block+i)+12, *(block+i)+13, *(block+i)+14 );
}
fclose(fptr);
fptr = fopen("states.txt", "r");
if (fptr == NULL) {
printf("Cannot Open Words File!\n");
return 0;
}
for(i=0; i<50; i++){
*(words+i) = (char*)malloc(20 * sizeof(char));
fgets(*(words+i), 20, fptr);
}
for(i=0; i<49; i++){
*(*(words+i) + strlen(*(words+i))-2) = '\0';
}
printf("Printing list of words:\n");
for(i=0; i<50; i++){
printf("%s\n", *(words + i));
}
printf("\n");
printf("Printing puzzle before search:\n");
printPuzzle(block, bSize);
printf("\n");
searchPuzzle(block, bSize, words, 50);
printf("\n");
printf("Printing puzzle after search:\n");
printPuzzle(block, bSize);
printf("\n");
return 0;
}
void printPuzzle(char** arr, int n){
for(int i = 0; i < n; i++){
printf("\n");
for(int j = 0; j < 15; j++){
printf("%c ", *(*(arr+i)+j));
}
}
}
void searchPuzzle(char** arr, int n, char** list, int listSize){
for(int i = 0; i < listSize; i++){
for(int j = 0; j < n; j++){
for(int k = 0; k < n; k++){
searchWord(j, k, n, arr, list, i);
}
}
}
}
void searchWord(int j, int k, int gridsize, char** arr, char** list, int listPos){
int wordlength = strlen(*(list+listPos));
if(j+wordlength <= gridsize){ //Horizontal
int i = 0;
while(i < wordlength && *(*(arr+(j+i))+k) == *(*(list+listPos)+i)){
i++;
}
if(i == wordlength){
while(i > 0 && *(*(arr+(j+i))+k) == *(*(list+listPos)+i)){
tolower(*(*(arr+(j+i))+k));
i--;
}
for(i = 0; i < wordlength; i++)
printf("%c", *(*(list+listPos)+i));
}
}
if(k+wordlength <= gridsize){ //Vertical
int i = 0;
while(i < wordlength && *(*(arr+j)+(k+i)) == *(*(list+listPos)+i)){
i++;
}
if(i == wordlength){
while(i > 0 && *(*(arr+j)+(k+i)) == *(*(list+listPos)+i)){
tolower(*(*(arr+(j+i))+k));
i--;
}
for(i = 0; i < wordlength; i++){
printf("%c", *(*(list+listPos)+i));
}
}
}
if(j+wordlength <= gridsize && k+wordlength <= gridsize){ //Diagonal
int i = 0;
while(i < wordlength && *(*(arr+(j+i))+k) == *(*(list+listPos)+i)){
i++;
}
if(i == wordlength){
while(i > 0 && *(*(arr+(j+i))+(k+i)) == *(*(list+listPos)+i)){
tolower(*(*(arr+(j+i))+(k+i)));
i--;
}
for(i = 0; i < wordlength; i++)
printf("%c", *(*(list+listPos)+i));
}
}
}

Print lines longer than 80 characters in C

I am not sure why wont this work.I am trying to print lines(from input) that are longer than 80 characters.But i dont get correct characters at all.I am not sure what am i doing wrong.Anyone there knows ??
Note: I dont want you to write me the whole new program doing this function (printing lines that are longer than 80).I just wanna know the wrong side of my program.Correction
Note:Last line overwrites the previous ones.
#include <stdio.h>
#define MAXARRAYSIZE 500
char c;
int i = 0;
int j = 0;
int jCopy = 0;
char line[MAXARRAYSIZE];
char linesToPrint[MAXARRAYSIZE][MAXARRAYSIZE];
void emptyArray(char theArray[]);
void InsertArrayIntoArray(char to[MAXARRAYSIZE][MAXARRAYSIZE], char from[], int toIndex, int lengthSoFar);
void printArray(char theArray[MAXARRAYSIZE][MAXARRAYSIZE], int lengthSoFarX);
int main(void) {
while ((c = getchar()) != EOF) {
if (i > MAXARRAYSIZE) {
i = 0;
}
if (j > MAXARRAYSIZE) {
j = 0;
}
if (c != '\n') {
line[i] = c;
i++;
//printf("%d",i);
} else {
printf("\n j:%d \n i:%d", j, i);
j++;
jCopy = j;
if (i >= 10) {
InsertArrayIntoArray(linesToPrint, line, j, i);
//printArray(linesToPrint, j, i);
}
emptyArray(line);
i = 0;
}
}
printArray(linesToPrint, jCopy);
}
void emptyArray(char theArray[]) {
int i;
for (i = 0; i < sizeof(theArray) / sizeof(theArray[0]); i++) {
theArray[i] = 0;
}
}
void InsertArrayIntoArray(char to[MAXARRAYSIZE][MAXARRAYSIZE], char which[], int toSize, int whichSize) {
int i, j;
//printf("\n To size: %d \t Which Size: %d",toSize,whichSize);
for (i = 0; i < toSize; i++) {
for (j = 0; j < whichSize; j++) {
to[i][j] = which[j];
}
}
}
void printArray(char theArray[MAXARRAYSIZE][MAXARRAYSIZE], int lengthSoFarX) {
int i, j;
for (i = 0; i < lengthSoFarX; i++) {
printf("\n Line %d :", i + 1);
printf(" %s\n", theArray[i]);
}
}
First of all the sizeof(theArray) cannot be taken because theArray is pointer as Joachim Pileborg pointed out.And the second mistake is in InsertArrayIntoArray function.
It should be like this :
void InsertArrayIntoArray(char to[MAXARRAYSIZE][MAXARRAYSIZE], char which[], int toSize, int whichSize) {
int i, j;
//printf("\n To size: %d \t Which Size: %d", toSize, whichSize);
for (j = 0; j < whichSize; j++) {
to[toSize][j] = which[j];
}
}

Arranging a character array using bubble sort

Here is my code so far. I am perfectly able to sort files holding numbers but clueless when it comes to characters. It takes in a file of my choosing and outputs another file with the sorted array. But so far all I'm getting are blank files and I can't figure out why.
So how can I fix my code to sort an array of characters and then output it?
#include <stdio.h>
int bubble_sort(char *a, int n);
int main(void) {
char a[10];
int n = sizeof a / sizeof a[10];
int i;
char inname;
char outname;
printf("Enter input name: ");
scanf("%s", &inname);
printf("Enter output name: ");
scanf("%s", &outname);
FILE *in, *out;
out = fopen(&outname, "w");
if ((in = fopen(&inname, "r")) == NULL) {
printf("File not found\n");
}
else {
for (int i = 0; i < 10; i++)
{
fscanf(in, "%s ", &a[i]);
}
bubble_sort(a, n);
for (i = 0; i < 10; i++) {
printf("%s\n", a[i]);
fprintf(out, "%s\n", a[i]);
}
}
fclose(in);
fclose(out);
return 0;
}
int bubble_sort(char *a, int n) {
int i, j;
char temp;
for (j = 1; j<n; j++)
{
for (i = 0; i<n - j; i++)
{
if ((int)a[i] >= (int)a[i + 1])
{
temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
}
return a[i];
}
The basic problem, as I can see, is with
scanf("%s", &inname);
In your code, inname is a single char, which cannot hold string inputs. You'll be needing an array.
You need to change
char inname;
char outname;
to
#define NAMSIZ 32
char inname[NAMSIZ] = {0};
char outname[NAMSIZ] = {0};
and then,
scanf("%31s", inname);
and accordingly.
Same problem exist with fscanf(in, "%s ", &a[i]);, too.

Resources