How to use a code with arrays and strings? - c

Here are the instructions I was given:
If the command word is find, read an additional integer and search the data set for that integer.
If the command word is print, print the array
Any other command word is an error.
No command word will be longer than 20 characters.
After reading the n+1 values, there will be one more integer (k) read from the keyboard.
Search the array for the value k. If found, print the location where k was found. (1 = data value, n = last data value).
If k is not found, print not found. This is not an error.
If there are more than one value k in the data, only print the location of the first one.
#include <stdio.h>
int main (void) {
int n;
scanf ("%d", &n);
if (n < 1) {
printf ("Error: one or more values must be provided.\n");
return 1;
}
int x [n];
int a;
a = 0;
while (a < n) {
scanf ("%d", x [a]);
a = a + 1;
}
int k;
scanf ("%d", &k);
int i;
i = 0;
while (i <= n-1) {
if (x[i] == k) {
break;
}
i = i + 1;
}
if (i < n) {
printf ("%d\n", k+1);
} else {
printf ("not found\n");
}
printf ("Error: invalid command\n");
return 0;
}
Suggested Strategy:
After reading the array data, read a string.
If the string is find, read integer k and perform a search.
If the string is print, do not read k, just print the data in the array.
If the string is not find or print, handle the error.

Shai'Tavia, I hope my answer will help you see how you may make your code work. You've got the first part down, but you will need to compare the command string given by the user to then make a decision on what to do next.
#include <stdio.h>
#include <string.h>
#define ARRAYLENGTH 8
void printArray(int *array, int length)
{
for (int i = 0; i < length; i++)
printf("%d ", array[i]);
printf("\n");
}
void search(int *array, int key)
{
int flag = 0;
for (int i = 0; i < ARRAYLENGTH; i++)
{
if (array[i] == key && flag == 0)
{
printf("found %d at index: %d\n", key, i);
flag = 1;
}
}
if (flag == 0)
printf("not found\n");
}
int main(void)
{
char command[20];
int indx = 0;
int array[] = {1, 4, 6, 8, 43, 61, 34, 2};
int n, flag = 0;
printf("How many times will we run?");
scanf("%d", &n);
if (n < 1)
{
printf("Error: one or more values must be provided.\n");
return 1;
}
do
{
printf("Enter the command word:");
scanf("%s", command);
if (strcmp(command, "find") == 0)
{
scanf("%d", &n);
search(array, n);
}
else if (strcmp(command, "print") == 0)
printArray(array, ARRAYLENGTH);
else
printf("Command not found\n");
} while (--n > 0);
printf("What is your final interger?");
scanf("%d", &n);
search(array, n);
return 0;
}

Related

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.

Factorial program in c

Trying to make a code that gets the factorial of the inputted number.
int factorial(int number, int i)
{
int endval;
for(i = number - 1; i>0; i--){
endval = number * i;
}
if (endval == 0){
printf("1");
}
return endval;
}
int main()
{
int endvalue, numA, numB;
char userchoice[1];
printf("Enter a choice to make (f for factorial): \n");
scanf("%s", userchoice);
if(strcmp(userchoice, "f")== 0){
printf("Enter a value to get it's factorial: ");
scanf("%d", &numA);
endvalue = factorial(numA, numB);
printf("%d", endvalue);
return 0;}
getch();
return 0;
}
For some reason the whole for loop doesn't do anything in the function when I set the answer (number*i)= endval. It just prints out the same number I inputted and gives me an absurd answer for 0!.
int factorial(int number, int i)
{
int endval;
for(i = number - 1; i>0; i--){
endval = number * i;
}
if (endval == 0){
printf("1");
}
return endval;
}
However the code works perfectly fine when I remove endval variable entirely (with the exception that it gets 0! = 10)
int factorial(int number, int i)
{
for(i = number - 1; i>0; i--){
number = number * i;
}
if (number == 0) {printf("1");}
return number;
}
Is there anything I missed in the code that's causing these errors?
A definiton of factorial is:
factorial(0) = 1
factorial(n) = n * factorial(n-1)
Note: Factorial is legal only for number >= 0
In C, this definition is:
int factorial(int number)
{
if (number < 0)
return -1;
if (number == 0)
return (1);
/*else*/
return (number * factorial(number-1));
}
#include <stdio.h>
#include <string.h>
int factorial(int number)
{
int endval=1;
for(int i = number ; i>0; i--){
endval *= i;
}
return endval;
}
int main()
{
int endvalue=0;
int numA=0;
char userchoice[1];
printf("Enter a choice to make (f for factorial): ");
int ret=scanf("%s", userchoice);
if (!ret){
printf("Error in scanf: %d", ret);
}
if(strcmp(userchoice, "f")== 0){
printf("Enter a value to get it's factorial: ");
scanf("%d", &numA);
endvalue = factorial(numA);
printf("%d", endvalue);
return 0;
}
getchar();
return 0;
}
Code with some changes will work
factorial() function can get only one argument.
As a good habit all variables must be initialized.
Add include statement to source and be explicit not rely on compiler.
As we use strcmp() we must include string.h
use standard getchar() instead of getch()
Also can check return value of library function scanf() to ensure reading is correct or not.
You can use warnings from compiler to get most of above notes. In gcc: gcc -Wall code.c
Use a debugger to run program line by line and monitor variables value in each steps or use as many printf() to see what happens in function call.
There are possibly few things to correct. See please attached code.
int factorial(int number)
{
if (number == 0){ return 1; }
int endval=1, i;
for(i = 1; i<=number; i++) { endval *= i; }
return endval;
}
int main() {
int endvalue, numA;
char userchoice[1];
printf("Enter a choice to make (f for factorial): \n");
scanf("%s", userchoice);
if(strcmp(userchoice, "f")== 0) {
printf("Enter a value to get it's factorial: ");
scanf("%d", &numA);
endvalue = factorial(numA);
printf("%d", endvalue);
return 0;
}
getch();
return 0;
}

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.

C program for assigning elements of a matrix without letters

I'm having trouble outputting an invalid statement if the user inputs a letter instead of a number into a 2D array.
I tried using the isalpha function to check if the input is a number or a letter, but it gives me a segmentation fault. Not sure what's wrong any tips?
the following code is just the part that assigns the elements of the matrix.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 10
void display(int matrix[][MAX], int size);
int main() {
int n, degree;
int matrix[MAX][MAX];
printf("Enter the size of the matrix: "); // assigning size of the matrix
scanf("%d", &n);
if (n <= 1 || n >= 11) { // can't be bigger than a 10x10 matrix
printf("Invalid input.");
return 0;
}
for (int i = 0; i < n; ++i) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
if (!isalpha(matrix[i][j])) { // portion I'm having trouble with
continue;
} else {
printf("Invalid input.");
return 0;
}
}
}
...
As the value of n will be number, we can solve it using string instead of int.
char num[10];
int n;
scanf("%s", num);
if(num[0] < '0' || num[0] > '9' || strlen(num) > 2){
printf("invalid\n");
}
if(strlen(num) == 1) n = num[0] - '0';
if(strlen(num) == 2 && num[0] != 1 && num[1] != 0) printf("invalid\n");
else n = 10;
Also we can use strtol() function to convert the input string to number and then check for validity.You can check the following code for it. I have skipped the string input part. Also you have to add #include<stdlib.h> at the start for the strtol() function to work.
char *check;
long val = strtol (num, &check, 10);
if ((next == num) || (*check != '\0')) {
printf ("invalid\n");
}
if(val > 10 || val < 0) printf("invalid\n");
n = (int)val; //typecasting as strtol return long
You must check the return value of scanf(): It will tell you if the input was correctly converted according to the format string. scanf() returns the number of successful conversions, which should be 1 in your case. If the user types a letter, scanf() will return 0 and the target value will be left uninitialized. Detecting this situation and either aborting or restarting input is the callers responsibility.
Here is a modified version of your code that illustrates both possibilities:
#include <stdio.h>
#define MAX 10
void display(int matrix[][MAX], int size);
int main(void) {
int n, degree;
int matrix[MAX][MAX];
printf("Enter the size of the matrix: "); // assigning size of the matrix
if (scanf("%d", &n) != 1 || n < 2 || n > 10) {
// can't be bigger than a 10x10 matrix nor smaller than 2x2
// aborting on invalid input
printf("Invalid input.");
return 1;
}
for (int i = 0; i < n; i++) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; j++) {
if (scanf("%d", &matrix[i][j]) != 1) {
// restarting on invalid input
int c;
while ((c = getchar()) != '\n') {
if (c == EOF) {
printf("unexpected end of file\n");
return 1;
}
}
printf("invalid input, try again.\n");
j--;
}
}
}
...
The isdigit() library function of stdlib in c can be used to check if the condition can be checked.
Try this:
if (isalpha (matrix[i][j])) {
printf ("Invalid input.");
return 0;
}
So if anyone in the future wants to know what I did. here is the code I used to fix the if statement. I am not expecting to put any elements greater than 10000 so if a letter or punctuation is inputted the number generated will be larger than this number. Hence the if (matrix[i][j] > 10000). May not be the fanciest way to do this, but it works and it's simple.
for (int i = 0; i < n; ++i) { // assigning the elements of matrix
printf("Enter the row %d of the matrix: ", i);
for (int j = 0; j < n; ++j) {
scanf("%d", &matrix[i][j]);
if (matrix[i][j] > 10000) { // portion "fixed"
printf("Invlaid input");
return 0;
}
}
}
I used a print statement to check the outputs of several letter and character inputs. The lowest out put is around and above 30000. So 10000 I think is a safe condition.

making a word search puzzle?

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.

Resources