making a word search puzzle? - c

I've made a program that allows you to choose the size of the grid and it allows you to enter up to 20 words. Now I have to insert the entered words horizontally into the original array using a function. The function must return a value for success and a value for failure to enter the word into the puzzle board. I need help getting started with what the actual function should look like along with the function prototype. Pseudocode would be helpful. I'm a fairly new programmer so any help is great. Thank you
#include<stdio.h>
#include<string.h>
void printmatrix(char matrix[][20],int);
void inserthor(char matrix[][20],int);
int main(void)
{
//declare variables
char matrix[20][20];
char words[20][100];
int x;
int a,b;
int i=0;
int n=0;
for (a=0;a<20;a++)
{
for (b=0;b<20;b++)
{
matrix[a][b] = '+';
}
}
while (x<10 || x>20)
{
printf("How large would you like the puzzle to be (between 10 and 20):\n");
scanf("%d",&x);
}
printmatrix(matrix,x);
//part 3
printf("Enter up to 20 words to hide in the puzzle.\n");
printf("Enter the word 'done' after your last word if entering less than 20 words.\n");
for (i = 0; i < 20; i++)
{
printf("Enter word %2d:\n", i+1);
if (scanf("%99s", words[i]) != 1 || strcmp(words[i], "done") == 0)
break;
}
n = i;
printf("%d words entered\n", n);
for (i = 0; i < n; i++)
printf("Word %2d = [%s]\n", i+1, words[i]);
return 0;
}
void printmatrix(char matrix[][20],int x)
{
int i,j;
printf("Empty Puzzle:\n");
for (i=0;i<x;i++)
{
for (j=0;j<x;j++)
{
printf(" %c ", matrix[i][j]);
}
printf("\n");
}
}

Your function prototype
void inserthor(char matrix[][20],int);
lacks the parameter with the word to be entered and the value to be returned. You could use
char *inserthor(char matrix[][20], int order, char *word)
{
int i, j, l = strlen(word);
for (i = 0; i < order; ++i)
for (j = 0; j <= order-l; ++j)
if (matrix[i][j] == '+') return memcpy(&matrix[i][j], word, l);
return NULL;
}
which returns the address of the inserted word for success and NULL for failure.

Related

Need some help how to enter a number and count it using array

I have to code in an array that can count an element. For example, if the user enters a 2, 2, 2, 1,1 then the user wants to count the number 2 then the result will be ELEMENT is 2 and FREQUENCY is 3. but I have a problem with the parts of " ENTER THE NUMBER YOU WANT TO BE COUNTED". I use scanf but when I run it I cannot enter any number.
Here's my code:
void frequency()
{
system("cls");
int num;
int count=0;
printf("Enter a number you want to be count: \n ");
scanf("i%", &num);
printf(" ELEMENT | FREQUENCY \n ");
for (i = 0; i<=n; i++)
{
if (a[i]==a[num])
count++;
}
printf(" \n %i ", num);
printf(" \t\t");
printf("%i \n ", count);
getch();
}
Your program requires understanding on two parts:
Get input and split input by delimiter, which can be done by using strtok.
Algorithm for finding the duplicated elements in an array.
#include <stdio.h>
#include <string.h>
int main() {
frequency();
return 0;
}
void frequency() {
char str[100];
printf("Enter a number you want to be count: \n ");
gets(str);
int init_size = strlen(str);
char delim[] = " ";
char *ptr = strtok(str, delim);
char *pch;
int arr[20];
int count = 0;
int ncount, i, j;
int a[count], Freq[count];
while(ptr != NULL) {
/*printf("'%s'\n", ptr);*/
/*Converts the string argument str to an integer (type int)*/
arr[count] = atoi(ptr);
/*strtok accepts two strings - the first one is the string to split, the second one is a string containing all delimiters*/
ptr = strtok(NULL, delim);
/*Initialize frequency value to -1*/
Freq[count] = -1;
count += 1;
}
/*Count the frequency of each element*/
for (i = 0; i < count; i++) {
ncount = 1;
for(j = i + 1; j < count; j++) {
/*Part to perform checking for duplicate elements*/
if(arr[i] == arr[j]) {
ncount++;
/*Make sure not to count frequency of same element again*/
Freq[j] = 0;
}
}
/*If frequency of current element is not counted*/
if(Freq[i] != 0) {
Freq[i] = ncount;
}
}
printf(" ELEMENT | FREQUENCY \n");
printf("-------------------------\n");
for (i = 0; i < count; i++) {
if(Freq[i] != 0) {
printf("\t%d\t\t\t%d\n", arr[i], Freq[i]);
}
}
}
Also, from your code:
You did not define i and n, which is required by your for loop. Also, since your for loop is for (i = 0; i<=n; i++), you have to define the value of n, which is the length of elements inputted by the user, in order to loop through the number of elements you expected.
int i, n, num;
...
...
for (i = 0; i<=num; i++)
Your scanf("i%", &num); should be scanf("%i", &num); instead.
You did not initialize your array a. You should have this line of code before assigning values to your array a. The value 20 can be adjusted by yourself depending on how many inputs are expected. Also, it can be coded in a flexible way instead of hardcoded as 20.
...
int i, num;
int count=0;
int a[20];
...
...
Lastly, it is a good practice to include the function's library before using it. In your case, you should include #include <conio.h> to use the getch() function.

Check if the user input matches one of the elements in the array

If the user inputs a value that matches with an int in the array continue the program else quit the program.
My issue is that the function loops the whole array and if it finds one of the values doesnt match it will quit.
//Check if the user input matches with one of the ints in the array
void check(int num, int arr[]) {
for (int i = 0; i < 3; i++) {
if (arr[i] != num) {
printf("Invalid input");
exit(0);
}
}
}
void main() {
int arr[3] = { 1, 2, 3 };
int num = 0;
for (int i = 0; i < 3; i++) {
printf("%d ", arr[i]);
}
printf("\nPLease enter a value which matches with the array %d", num);
scanf("%d", &num);
check(num, arr);
}
void check(int num, int arr[]) {
for (int i = 0; i < 3; i++) {
if (arr[i] == num) {
return;
}
}
printf("Invalid input");
exit(0);
}
Your issue is that checks a single element and judges the input on that specific value. If it has run through each value and the function has still not returned, there is not match and we can exit the program.
You have a logic flaw in the check function: you should output the message and quit if none of the values match the input. You instead do this if one of the values does not match. The check always fails.
Here is a modified version:
#include <stdio.h>
//Check if the user input matches with one of the ints in the array
void check(int num, const int arr[], size_t len) {
for (size_t i = 0; i < len; i++) {
if (arr[i] == num) {
// value found, just return to the caller
return;
}
}
// if we get here, none of the values in the array match num
printf("Invalid input: %d\n", num);
exit(1);
}
int main() {
int arr[3] = { 1, 2, 3 };
size_t len = sizeof(arr) / sizeof(*arr); // length of the array
int num;
for (size_t i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n");
printf("Please enter a value which matches with the array: ");
if (scanf("%d", &num) == 1) {
check(num, arr, len);
} else {
// input missing or not a number
printf("Invalid input\n");
}
return 0;
}
You are right, you do exit once arr[i] != num (When the value is not the same as the i:th element in the array).
So, you could change it to: arr[i] == num. If it is the same, perhaps print "You got it!", and a return afterwards.

Cannot continue after scanf function

I am trying to create a program that asks user to build an array with numbers only, and also to removes a specific element asked to the user
My problem is that when I compile and run the code, it seems to get stucked at my scanf function. I have placed indicators to know where my code is currently running at as shown in my program below
note: i cannot use pointers
#include <stdio.h>
#define MAX_LEN 5
void remover(int list[], int item)
{
int temp[MAX_LEN] = {'e', 'e', 'e', 'e', 'e'}; //e stands for EMPTY
int i, j, k;
i = j = k = 0;
for(i = 0; i < MAX_LEN ; i++)
{
if(list[i] != item) //if array index doesnt match with item to be removed
{
temp[j++]=list[i]; //copy element to temporary array
}
}
for(k; k<MAX_LEN; k++) //copy TEMP into LIST
{
list[k] = temp[k];
}
}
void add(int list[], int item, int nth)
{
printf("\nentering add func listing");
list[nth] = item;
}
int main()
{
int list[MAX_LEN];
int item_number, remove_number;
int inputFlag = 1;
int i;
putchar('\n');
printf("\n------------------------------------------------------");
printf("\n-------___Ordered List Array Implementation____-------");
printf("\n------------------------------------------------------");
printf("\nEnter 5 elements to be filled in: ");
for( i = 0; i<6 && inputFlag; i++)
{
printf("\nEnter item number %d in list\t", i+1);
scanf("%d\n", item_number); //I have tried removing the trailing \n after %d but still gives the same problem
printf("\n..Done scanning input"); //PROGRAM CANNOT CONTINUE HERE
if(item_number != sizeof(int))
{
printf("\nPlease input integers. Terminating...");
exit(0);
}
add(list, item_number, i);
printf("\nAdded to add func");
}
printf("\nShowing index of list.. ");
for(int j=0; j<i; j++)
printf("[%d] ==> %d", j, list[j]);
printf("\n------------------------------------------");
printf("\n__________________________________________");
printf("\nEnter item to be removed: ");
scanf("%d\n", remove_number);
remover(list, remove_number);
printf("\nNew list with item ' %d ' removed", remove_number);
putchar('\n');
for(int m = 0; m < MAX_LEN; m++)
{
if(list[m] == sizeof(int))
printf("\n[%d] ==> %d", m, list[m]);
if(list[m] == sizeof(char))
printf("\n[%d] ==> %c", m, list[m]);
}
}
You forgot to put & in your scanf call.
For e.g. you should try:
scanf("%d\n", &item_number);
and it should work fine.
Checkout this article for more information on scanf.
scanf or scan formatted string, requires you the location (address) of the variable in which you want to store your value.
Checkout this question for more information.

Trying to remove substring from string in C, keep failing

I know this question has been asked many times before but I simply cannot get my head around what I am doing wrong. Everytime I make some progress I get a new error. The code I am using is really basic because I am a newbie and our professor requires the usage of scanf and gets. This is my code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
int identify(char[], char[]);
int remove(char[], char[], int);
int scan(choice)
{
while(choice < 0 || choice > 7)
{
printf("Invalid input, choose again\n");
scanf("%d", &choice);
}
return choice;
}
int main()
{
char sentence[MAX_SIZE], word[MAX_SIZE];
int choice, i, j, k, deikths;
printf("Choose one of the following:\n");
printf("1. Give sentence\n");
printf("2. Subtract a word\n");
printf("3. Add a word\n");
printf("4. Count the words\n");
printf("5. Count the sentences\n");
printf("6. Count the characters\n");
printf("7. Is the phrase a palindrome?\n");
printf("0. Exit\n");
scanf("%d", &choice);
if(scan(choice) == 1)
{
printf("Give sentence:\n");
gets(sentence);
gets(sentence);
printf("%s\n", sentence);
}
else(scan(choice) == 2);
{
printf("Give word you want to subtract\n");
gets(word);
printf("%s", word);
deikths = identify(sentence, word);
if(deikths != -1)
{
remove(sentence, word, deikths);
printf("Sentence without word: %s\n", sentence);
}
else
{
printf("Word not found in sentence.\n");
}
}
}
int identify(char sentence[], char word[])
{
int i, j, k;
for(k = 0; word[k] != '\0'; k++);
{
for(i = 0, j = 0; sentence[i] != '\0'; i++)
{
if(sentence[i] == word[j])
{
j++;
}
else
{
j = 0;
}
}
}
if(j == 1)
{
return(i - j);
}
else
{
return -1;
}
}
int remove(char sentence[], char word[], int deikths)
{
int i, k;
for(k = 0; word[k] != '\0'; k++)
{
for(i = deikths; sentence[i] != '\0'; i++)
{
sentence[i] = sentence[i + k + 1];
}
}
}
The error I am getting, is that the remove function has conflicting types. Any help with fixing my code will be greatly appreciated, or even an alternative solution to my problem would bre great.
As established in the comments, the compiler error is generated because remove is already defined in the stdio.h. After changing, the name the code compiles successfully, but still doesn't work as expected.
identify is the function which is meant to find whether a substring exists in a string and return its position. This is very similar to how strstr from the standard library works - I'd suggest having a look at an implementation of that function, to better understand how this is done.
The function you implemented only correctly finds substrings of length 1, at the end of the string. I have highlighted errors in the code below which cause this.
int identify(char sentence[], char word[])
{
int i, j, k;
for(k = 0; word[k] != '\0'; k++); // <- this loops is never actually ran because of the trailing semicolon - this is however a good thing as it is redundant
{
for(i = 0, j = 0; sentence[i] != '\0'; i++)
{
if(sentence[i] == word[j])
{
j++;
}
else
{
j = 0; // <- this makes it so only matches at the end can be found - otherwise, j is just reset back to 0
}
}
}
if(j == 1) // <- this makes it so only matches of length 1 can be found
{
return(i - j); // <- this is only correct if the match is at the end of the sentence
}
else
{
return -1;
}
}
strremove is inefficient due to the nested loops and the range of characters copied needs to be shortened - right now data is access beyond the end of the array.
int strremove(char sentence[], char word[], int deikths)
{
int i, k;
for(k = 0; word[k] != '\0'; k++) // <- this loop is redundant
{
for(i = deikths; sentence[i] != '\0'; i++) // <- you need to add range checking to make sure sentence[i+k+1] doesn't go beyond the end of the string
{
sentence[i] = sentence[i + k + 1];
}
}
}
I will leave the problems in main as an exercise to you - this is an assignment after all.

Segmentation Fault: 11 C sometimes

I'm trying to run a program in C on my mac that asks the user to input a set of names. The program then sorts and capitalizes all the names and prints them capitalized and sorted. It then allows the user to search for a name. However, most of the time (but not every time) I try to run the code it returns a segmentation fault: 11 error. My guess is that the problem has something to do with fgets or my array but I don't really know.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SIZE 50
#define LENGTH 50
#define TRUE 1
#define FALSE 0
void printList(char names[SIZE][LENGTH], int length);
void toUpperCase(char names[SIZE][LENGTH], int length);
void sort(char names[SIZE][LENGTH], int length);
void startSearch(char names[SIZE][LENGTH], int length);
int binSearch(char names[SIZE][LENGTH], int l, int r, char x[LENGTH]);
int main(void){
char names[SIZE][LENGTH]; //stores the list of names
printf("Enter student names (q to stop)...\n");
int i = 0;
do {
printf("Student name #%d: ", i);
fgets(names[i], LENGTH, stdin); //fill the list of names
int len = strlen(names[i])-1; //fgets includes \n character
if(names[i][len] == '\n') //if the last character is \n
names[i][len] = '\0'; //change it to \0
if(strcmp(names[i], "") == 0)
printf("Invalid input: Type a name\n");
else
i++;
}
while(strcmp(names[i-1],"q")!=0 && i<SIZE); //Stop collecting names after input "q"
//or if the names array is full
int length = i-1; //# of names in the names array
sort(names, length);
toUpperCase(names, length);
printList(names, length);
startSearch(names, length);
printf("Done!\n");
return 0;
}
//Converts all the names in the names array to upper case
void toUpperCase(char names[SIZE][LENGTH], int length){
for(int i = 0; i < length; i++){
for(int j = 0; names[i][j]!='\n'; j++){
if(islower(names[i][j]))
names[i][j] = toupper(names[i][j]);
}
}
}
//sorts the names in the names array (bubble sort)
void sort(char names[SIZE][LENGTH], int length){
int i, j;
char temp[LENGTH];
for (i = 0; i < length-1; i++)
for (j = 0; j < length-i-1; j++)
if (strcmp(names[j],names[j+1])>0){
strcpy(temp, names[j]);
strcpy(names[j], names[j+1]);
strcpy(names[j+1], temp);
}
}
//prints the names in the names array
void printList(char names[SIZE][LENGTH], int length){
printf("Student list: [\n");
for(int i = 0; i < length; i++)
if(i == length-1)
printf("\t%s\n", names[i]);
else
printf("\t%s,\n", names[i]);
printf("]\n");
}
//The first method for searching the list
void startSearch(char names[SIZE][LENGTH], int length){
char search[LENGTH];
while(strcmp(search, "q")!=0){
printf("Enter a name to search (q to exit): ");
fgets(search, LENGTH, stdin); //gets the name to search
int len = strlen(search)-1;
if(search[len] == '\n')
search[len] = '\0';
if(strcmp(search, "q") == 0) //if entered value is q
break; //break out of the loop
//Since the list is all upper case change the search value to upper case
for(int j = 0; search[j]!='\n'; j++){
if(islower(search[j]))
search[j] = toupper(search[j]);
}
printf("Searching for %s ...\n", search);
// if binSearch returns true then the item is in the list
if(binSearch(names, 0, length-1, search) == TRUE)
printf("%s is in the list!\n", search); /
else
printf("%s is NOT in the list!\n", search);
}
}
//binary search for the names array
int binSearch(char names[SIZE][LENGTH], int l, int r, char x[LENGTH]){
while (l <= r)
{
int m = l + (r-l)/2;
if(strcmp(names[m], x) == 0)
return TRUE;
if(strcmp(names[m], x) < 0)
l = m + 1;
else
r = m - 1;
}
return FALSE;
}
I assume you're using fixed arrays of SIZE and LENGTH for learning purposes. For actual string-related work, you'd do well to heed kpra's advice and using the more complex, but more powerful, pointers (allocating them and deallocating at need).
In your reading loop you kill all the "\n"'s replacing them with zeroes.
Yet in your toUppercase() code you look for a "\n" instead of a 0x0. This risks blowing the buffer:
//Converts all the names in the names array to upper case
void toUpperCase(char names[SIZE][LENGTH], int length){
for(int i = 0; i < length; i++){
for(int j = 0; names[i][j]!='\n'; j++){
// what happens here if \n is not found and j exceeds SIZE?
if(islower(names[i][j]))
names[i][j] = toupper(names[i][j]);
}
}
}
You could replace \n with 0x0, but I think a safer loop would be:
for(int j = 0; j < SIZE; j++) {
if (yourstring[j] == 0) {
break;
}
This way you're sure never to overshoot SIZE, and the cycle is ended anyway if the end of string is found. Notice that this '\n' comparison is used also in the search loop.

Resources