Cannot continue after scanf function - c

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.

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.

Create a Menu for users to choose whether they want to add/remove/search for numbers using an array

I want to build a simple user Menu for the user to add/remove and to search for numbers through an array. However, the problem that I am facing is that after successfully running the code and adding numbers to a global array. When choosing the remove option, It showed the list of the array but array1 is not the value of the array I entered, but a total length of the array instead.enter image description here. Please show me which parts that I coded or wrote wrong and excuse me for my bad english! Thank you so much in advance.
#include <stdio.h>
#include <string.h>
int arr[] = {};
int arrLength = 0;
void add(int lengthCheck){
int i,n,check = 0;
do{
printf("\nPlease add a number: ");
scanf("%d",&n);
fflush(stdin);
arr[lengthCheck] = n;
lengthCheck++;
printf("\nNew Array:");
for (i = 0; i < lengthCheck; i++){
printf("\t%d ", arr[i]);
}
printf("\n\n Do you want to continue adding? (y = 0 | n = 1)\n");
scanf("%d", &check);
fflush(stdin);
} while (check < 1);
arrLength = lengthCheck;
}
void remove(int lengthCheck){
int m, i, loop, count = 0;
printf("\nArray:");
for(loop = 0; loop < lengthCheck; loop++){
printf(" %d", arr[loop]);
}
printf("\n\nPlease chooose a number to remove: ");
scanf("%d",&m);
fflush(stdin);
for(loop = 0; loop < lengthCheck; loop++) {
if(arr[loop] == m) {
break;
}
count++;
}
for(i=count; i<lengthCheck - 1; i++)
{
arr[i] = arr[i + 1];
}
lengthCheck--;
printf("\nNew array are : ");
for(i=0; i<lengthCheck; i++)
{
printf("%d\t", arr[i]);
}
}
void search(int arrLength){
int check, loop, t, u;
printf("\nPlease enter a number to check if it exists in the array: ");
scanf("%d",&check);
fflush(stdin);
for(loop = 0; loop < arrLength; loop++) {
if(arr[loop] == check) {
printf("\n\tPosition number %d in the array contains %d\n\n", t,check);
u++;
}
t++;
}
printf("The number %d exist in %d position(s) of the array",check,u);
}
int main(){
int ch, z;
for (z = 0; z < 1;) {
printf("Enter Choice: \n\t(0) for add \n\t(1) for remove \n\t(2) for search\n\t(3) for exit\n");
scanf("%d", &ch);
fflush(stdin);
switch(ch) {
case 0:
add(arrLength);
break;
case 1:
remove(arrLength);
break;
case 2:
search(arrLength);
break;
case 3:
z = 1;
break;
}
}
return 0;
}
you cannot declare an empty array and just add values to it in C.
int arr[] = {};
You need to allocate space for your array upfront, or using malloc to allocate the memory for it later.
This will allocate memory space to store three ints in they array and initialize each element to zero:
int arr[3] = {0};
You will have to check that it never goes above the number of elements declared in the array. If you try to use more space than pre-allocated in the array, you are causing a buffer overflow and all it does is corrupt memory.

Wrong Results Being Printed in C After Being Inserted in 2D Char Array

int const size = 100;
float grades[size];
char students[size][size];
char temp_students[size][size];
int main() {
int length = 0;
int i = 0;
float g = 0;
printf("How many students do you want to enter? \n ");
scanf("%d", &length);
while((i < length)){
printf("Enter the name and grade \n");
// scanf("%s", students[i]);
char temp;
scanf("%c",&temp); // temp statement to clear buffer
scanf("%[^\n]", students[i]);
strcpy(temp_students[i], students[i]);
printf("Enter the grade again \n");
scanf(" %f", &g);
grades[i] = g;
insertion_sort_float(grades, g, length);
insertion_sort_string(students, students[i], length);
i++;
}
i--;
print_report(grades, students, length);
}
void print_report(float grades[], char students[size][size], int number){
printf("Students Test Report \n");
printf("Students that took the test: %d \n", number);
for (int i = 0; i < number; i++){
for(int j = 0; j < number; j++){
printf("%c", students[i][j]);
}
printf("\n");
}
double average = average_number(grades, number);
double median = median_number(grades, number);
double highest = max_number(grades, number);
double lowest = min_number(grades, number);
printf("Average: %f \n Median: %f \n Highest: %f \n Lowest: %f \n", average, median, highest, lowest);
}
void insertion_sort_string(char students[size][size], char string[], int array_size) {
if (array_size+ 1 < size) {// only do insert when there is free space in array
if (array_size == 0)//empty array, insert at the top directly
strcpy(students[0], string);
int insert_index;//to identify the location
for (int i = 0; i < array_size + 1; i++) {
insert_index = i;
if (strcmp(students[i], string)) // due the sorted property of array,
break;// where the first bigger item showes up, where we should insert    
}//end of the first for loop
// if we don't find any bigger item, inset_index will equal to element_num, which means we insert at the tail
for (int j = array_size; j > insert_index; j--) {
strcpy(students[j], students[j-1]);
}// end of the second loop
strcpy(students[insert_index], string); // do the insert    
} else {
printf("overflow!");
return;
}
}
This is what happens when the code is run:
Write a program that allows a user to enter the names of students that took a test along with the grades they received.
I am not sure why none of the other names are being stored. Only Gerar is being printed. Also the entire string should be printed: "Gerard 78.5", but that is not happening either.
Some code omitted for post purposes. But important code is included

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.

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