Why does i never get past 1? - c

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++;
}

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]);

C program to insert elements into an array until user inputs a 0 or less number

I'm trying to make a C program to insert elements into an array until user inputs a 0 or less number, as the title says. But when I print the array out, it doesn't show the numbers I inputted. I have tried using a while as well as do-while loops but without success.
#include <stdio.h>
int main() {
int data[100];
int i;
for (i = 0; i < 100; i++) {
printf("Input your number:\n");
scanf("%d", &data[i]);
if (data[i] <= 0) {
break;
}
}
printf("Your array:");
int n = sizeof(data[i]);
for (int i = 0; i < n; i++) {
printf("%d ", &data[i]);
}
}
Try this:
#include <stdio.h>
int main() {
int data[100];
int i;
int counter = 0;
for (i = 0; i < 100; i++) {
printf("Input your number:\n");
scanf("%d", &data[i]);
counter++;
if (data[i] <= 0) {
break;
}
}
printf("Your array:");
for (int j = 0; j < counter - 1; j++) {
printf("%d ", data[j]);
}
}
The problem was that you had printf("%d ", &data[i]); instead of printf("%d ", data[i]);.
And also you've trying to get the sizeof() of an element data[i], not the size of the whole array. That's why there's counter in my code.
int n = sizeof(data[i]);
this is wrong, you want
int n = i;
sizeof(data[i]) gives you the size of an int (4 on my machine)
On the other hand, you need to check the result of scanf, if a bad input is entered do not increment the counter, something like:
int i = 0;
while (i < 100)
{
int res = scanf("%d", &data[i]);
if (res == EOF)
{
break;
}
if (res == 1)
{
if (data[i] <= 0)
{
break;
}
i++;
}
else
{
// Sanitize stdin
int c;
while ((c = getchar()) != '\n');
}
}
Finally, scanf wants a pointer to the object, but this is not the case of printf:
printf("%d ", &data[i])
should be
printf("%d ", data[i])

Segmentation Fault when looping through 2D Char Array, Wordsearch

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');
}
}

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));
}
}
}

Fgets and sscanf not waiting for input C

Originally I was using scanf, but I was running into the newline char getting stuck in the stdin. Everything I have read was saying to switch to fgets and use sscanf instead. With that, I decided to switch to that...but that still is not working. Below you will find my code. My question is, what am I doing wrong with my fgets and sscanf that is causing it to not wait for the user input?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct f_in{
char outline;
int lines;
int rows;
int num_args;
} F_IN;
typedef struct args_in {
char in_string[20];
int t_format;
} ARGS_IN;
void printInterface(char argQs[5][50], char argChar);
int main(int argv, char** argc){
char defaultQuestions[5][50] = { { "1) What char for border?" }
, { "2) Add question" }
, { "3) Remove Question" }
, { "4) Print last answers" }
, { "5) Exit" } };
int commandEntry, exitFlag;
char borderChar = '*', addQ[50],userInp[1];
exitFlag = 1;
while (exitFlag){
printInterface(defaultQuestions, borderChar);
printf("Enter the integer value for the command you wish to select: ");
fgets(userInp, sizeof(userInp),stdin);
sscanf(userInp,"%d", &commandEntry);
printf("\nYou selected: %s\n", defaultQuestions[commandEntry - 1]);
userInp[0] = 0;
if (commandEntry == 1){
printf("Please enter the character you wish to be the border: ");
fgets(userInp,sizeof(userInp),stdin);
sscanf(userInp,"%c",&borderChar);
}
else if (commandEntry == 2){
printf("What question would you like to add? (only enter 50 char max)\n");
fgets(addQ, 50, stdin);
printf("This was your question: %s", addQ);
}
else if (commandEntry == 5){
printf("Goodbye!\n");
exitFlag = 0;
}
}
return 0;
}
void printInterface(char argQs[5][50], char argChar){
int i, j;
int lineCnt = 13;
int borderLen = 75;
for (i = 0; i<100; i++){
printf("\n");
}
for (i = 0; i<lineCnt; i++){
if (i == 0 || i == lineCnt - 1){
for (j = 0; j<borderLen; j++){
printf("%c", argChar);
}
printf("\n");
}
else if (i >= 3 && i <= 10){
printf("%c %s", argChar, argQs[i - 3]);
for (j = 0; j < ((borderLen - strlen(argQs[i - 3]))-6); j++){
printf(" ");
}
printf("%c\n", argChar);
}
else{
for (j = 0; j<borderLen; j++){
if (j == 0){
printf("%c", argChar);
}
else if (j == (borderLen - 1)){
printf("%c\n", argChar);
}
else{
for (j = 0; j<borderLen; j++){
if (j == 0){
printf("%c", argChar);
}
else if (j == (borderLen - 1)){
printf("%c\n", argChar);
}
else{
printf(" ");
}
}
}
}
for (i = 0; i<10; i++){
printf("\n");
}
}
"userInp[1] only allows enough memory to store the terminating '\0'"
- user312023

Resources