scanf not passing value to variable - c

I wanted to ask a little bit about scanf in C using Xcode IDE. If I not initially set value for variable choice, anytime I open my program and enter any choice(either 1/2) it will go to else case every time. So I check the value after select any choice then I got a strange number. Could you please take a look at my code. Thank you in advance.
Here's my actual code:
/* Bubble Sort using MPI */
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>
#define N 1000
double startT,stopT;
double startTime;
void showElapsed(int id, char *m)
{
printf("%d: %s %f secs\n",id,m,(clock()-startTime)/CLOCKS_PER_SEC);
}
void showVector(int *v, int n, int id)
{
int i;
printf("%d: ",id);
for(i=0;i<n;i++)
printf("%d ",v[i]);
putchar('\n');
}
int * merge(int *v1, int n1, int *v2, int n2)
{
int i,j,k;
int * result;
result = (int *)malloc((n1+n2)*sizeof(int));
/*
i : pointer of v1
j : pointer of v2
k : pointer of k
*/
i=0; j=0; k=0;
while(i<n1 && j<n2)
if(v1[i]<v2[j])
{
result[k] = v1[i];
i++; k++;
}
else
{
result[k] = v2[j];
j++; k++;
}
if(i==n1)
while(j<n2)
{
result[k] = v2[j];
j++; k++;
}
else
while(i<n1)
{
result[k] = v1[i];
i++; k++;
}
return result;
}
void swap(int *v, int i, int j)
{
int t;
t = v[i];
v[i] = v[j];
v[j] = t;
}
void sort(int *v, int n)
{
int i,j;
for(i=n-2;i>=0;i--)
for(j=0;j<=i;j++)
if(v[j]>v[j+1])
swap(v,j,j+1);
}
int main(int argc, char **argv)
{
int * data;
int * chunk;
int * other;
int m,n=N;
int id,p;
int s;
int i;
int step;
int choice = 0;
//start asking user to select option between sequential or parallel version of BubbleSort
printf(":: Welcome to BubbleSort Project for CSS333 ::\n");
printf("Please select option that you prefer\n");
printf("Type \"1\" for sequential mode or \"2\" for parallel mode\n");
printf("");
fflush(stdout);
scanf("Enter here: %d", &choice);
printf("Test value of choice(should be either 1 or 2): %d\n", choice);
//end asking
if(choice == 1){
// do seq
printf("You have selected option 1 which is running BubbleSort in Sequential mode\n");
printf("Please wait...");
}
else if(choice == 2){
// do parallel
printf("You have selected option 2 which is running BubbleSort in parallel mode\n");
printf("Please wait...");
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&p);
if(id==0)
{
int r;
srandom(clock());
s = n/p;
r = n%p;
data = (int *)malloc((n+p-r)*sizeof(int));
for(i=0;i<n;i++)
data[i] = random();
if(r!=0)
{
for(i=n;i<n+p-r;i++)
data[i]=0;
s=s+1;
}
startT = clock();
MPI_Bcast(&s,1,MPI_INT,0,MPI_COMM_WORLD);
chunk = (int *)malloc(s*sizeof(int));
MPI_Scatter(data,s,MPI_INT,chunk,s,MPI_INT,0,MPI_COMM_WORLD);
sort(chunk,s);
}
else
{
MPI_Bcast(&s,1,MPI_INT,0,MPI_COMM_WORLD);
chunk = (int *)malloc(s*sizeof(int));
MPI_Scatter(&data,s,MPI_INT,chunk,s,MPI_INT,0,MPI_COMM_WORLD);
sort(chunk,s);
}
step = 1;
while(step<p)
{
if(id%(2*step)==0)
{
if(id+step<p)
{
MPI_Recv(&m,1,MPI_INT,id+step,0,MPI_COMM_WORLD,&status);
other = (int *)malloc(m*sizeof(int));
MPI_Recv(other,m,MPI_INT,id+step,0,MPI_COMM_WORLD,&status);
chunk = merge(chunk,s,other,m);
s = s+m;
}
}
else
{
int near = id-step;
MPI_Send(&s,1,MPI_INT,near,0,MPI_COMM_WORLD);
MPI_Send(chunk,s,MPI_INT,near,0,MPI_COMM_WORLD);
break;
}
step = step*2;
}
if(id==0)
{
FILE * fout;
stopT = clock();
printf("%d; %d processors; %f secs\n",N,p,(stopT-startT)/CLOCKS_PER_SEC);
fout = fopen("result","w");
for(i=0;i<s;i++)
if (chunk[i] != 0)
fprintf(fout,"%d\n",chunk[i]);
fclose(fout);
}
MPI_Finalize();
}
else{
printf("Invalid value\n");
printf("Program exiting...\n");
exit(0);
}
}

This is your problem:
scanf("Enter here: %d", &choice);
You might be expecting this to display "Enter here: " then accept a number as input and store it in the variable choice. But that's not what it does.
What this does is that it goes through the formatting string ("Enter here: %d"), one character by one. For each character that is not '%', it reads a character from stdin and compares them together. If they don't match, it pushes the character back to the buffer of stdin and stops scanning.
So unless the user types in something starting with Enter here: followed immediately by a number, it fails at reading that number.
What you probably wanted to do is to:
printf("Enter here: ");
scanf("%d", &choice);
(and then read the documentation for scanf().

Related

How to remove the last comma in comma separated prime numbers within a range?

I have the code for finding prime numbers within a range.
The problem is to remove the last comma.
#include<stdio.h>
int main()
{
int a,b,i,x,c,f=1;
scanf("%d%d",&a,&b);
for(x=a;x<=b;(x++,f=0))
{
for(i=2;i<x;i++)
{
if(x%i==0)
{
f=1;
}
}
if(f==0)
printf("%d,",x);
}
}
But the output contains an extra comma in the last.
For example
2,3,5,7,
whereas the expected output is
2,3,5,7
Instead of flag you can decide directly what you want to print between numbers
And note that you can break out of the internal loop as soon as f is set to 1
#include<stdio.h>
int main()
{
int a,b,i,x,c,f=1;
const char* delim = "";
scanf("%d%d",&a,&b);
for(x=a; x<=b; (x++,f=0))
{
for(i=2; i<x; i++)
{
if(x%i==0)
{
f=1;
break; //no need to continue the checking
}
}
if(f==0) {
printf("%s%d",delim,x);
delim = ", ";
}
}
putchar('\n');
}
#include<stdio.h>
int main()
{
int a,b,i,x,c,f=1;
char backspace = 8;
scanf("%d%d",&a,&b);
for(x=a;x<=b;(x++,f=0))
{
for(i=2;i<x;i++)
{
if(x%i==0)
{
f=1;
}
}
if(f==0)
printf("%d,",x);
}
printf("\b"); // or printf("%c", backspace);
}
Add another flag, just a simple counter that tells you if you are printing the first time then check the flag to decide what to print, e.g.
#include<stdio.h>
int main()
{
int a,b,i,x,c,first=0,f=1;
scanf("%d%d",&a,&b);
for(x=a;x<=b;(x++,f=0))
{
for(i=2;i<x;i++)
{
if(x%i==0)
{
f=1;
}
}
if(f==0)
{
if(first==0){
printf("%d",x);
}else{
printf(",%d",x);
}
first++
}
}
}
Use a flag to detect the first occurrence of printf() and print the first number as such without any ,. For consecutive number printing precede with ,
#include<stdio.h>
int main()
{
int a,b,i,x,c,f=1,flag=0;//Flag to mark first occurrence
scanf("%d%d",&a,&b);
for(x=a;x<=b;(x++,f=0))
{
for(i=2;i<x;i++)
{
if(x%i==0)
{
f=1;
break;// Once the condition fails can break of the for loop as it fails for the prime number condition at the first case itself
}
}
if(f==0)
{
if(flag==0)
{//Check if it is first time
printf("%d",x);
flag = 1;//If so print without ',' and set the flag
}
else
printf(",%d",x);// On next consecutive prints it prints using ','
}
}
}
This method also avoids the , when only one number is printed.
Eg: When input is 2 and 4. It prints just 3 and not 3,
Simply you need odd number best practice for minimum loop is given below;
#include<stdio.h>
int main()
{
int a,b,i,x,c,f=1;
scanf("%d%d",&a,&b);
while (a < b)
{
if ( (a%2) == 1) {
printf("%d", a);
if ( (a + 1) < b && (a + 2) < b)
printf(",");
}
a = a + 1;
}
}
please check from the site
http://rextester.com/MWNVE38245
Store the result into a buffer and when done print the buffer:
#include <stdio.h>
#include <errno.h>
#define RESULT_MAX (42)
size_t get_primes(int * result, size_t result_size, int a, int b)
{
int i, x, f = 1;
size_t result_index = 0;
if (NULL == result) || (0 == result_size) || ((size_t) -1 == result_size))
{
errno = EINVAL;
return (size_t) -1;
}
for (x = a; x <= b; (x++, f = 0))
{
for (i = 2; i < x; i++)
{
if (x % i == 0)
{
f = 1;
break;
}
}
if (f == 0)
{
result[result_index] = x;
++result_index;
if (result_size <= result_index)
{
fprintf(stderr, "Result buffer full. Aborting ...\n");
break;
}
}
}
return result_index;
}
int main(void)
{
int a = 0, b = 0;
int result[RESULT_MAX];
scanf("%d%d", &a, &b);
{
size_t result_index = get_primes(result, RESULT_MAX, a, b);
if ((size_t) -1 == result_index)
{
perror("get_primes() failed");
}
else if (0 == result_index)
{
fprintf(stderr, "No primes found.\n");
}
else
{
printf("%d", result[0]);
for (size_t i = 1; i < result_index; ++i)
{
printf(", %d", result[i]);
}
}
}
return 0;
}
This example uses a simple fixed-size buffer, if this does not suite your needs replace it by a dynamic one.
This is more of a "language-agnostic" problem: "How do I output a comma-separated list without a final comma?" It is not specifically about prime numbers.
You seem to be thinking of you list as a series of [prime comma] units. It isn't. A better way to think of it is as a single prime as the head of the list, followed by a tail of repeated [comma prime] units.
Some pseudocode to illustrate the general idea:
outputList(theList)
separator = ", "
output(theList.firstItem())
while (theList.hasMoreItems())
output(separator)
output(theList.nextItem())
endwhile
return
/* this is just logic */
for(i=2;i<=n;i++)
{
k=0;
for(j=2;j<=i/2;j++)
{
if(i%j==0)
k=1;
}
if(k==0)
{
c++;
c++;
}
}
System.out.println(c);
for(i=2;i<=n;i++)
{
k=0;
for(j=2;j<=i/2;j++)
{
if(i%j==0)
k=1;
}
if(k==0)
{
System.out.print(i);
b++;
if(b!=c-1)
{
System.out.print(",");
b++;
}
}
}
}
}
//comma separated values
#include <bits/stdc++.h>
using namespace std;
int Prime(int a, int n){
bool prime[n+1];
memset(prime,true,sizeof(prime));
for(int p=2;p*p<=n;p++){
if(prime[p]==true){
for(int i=p*p ; i<=n; i+=p ){
prime[i] = false;
}
}
}
for(int i = 2;i<= n;i++){
if(i==2) cout<<i; // here is the logic first print 2 then for other numbers first print the comma then the values
else if(prime[i]) cout<<","<<i;
}
}
int main(){
int a =2 ;
int n = 30;
Prime(a , n);
}
#include <stdio.h>
int main()
{
int i, j, n, count;
scanf("%d", &n);
for(i=2; i<n; i++)
{
count=0;
for(j=2; j<n; j++)
{
if(i%j==0)
count++;
}
if(count==1)
printf("%d," i);
}
printf("\b \b");
}
\b is a nondestructive backspace. It moves the cursor backward, but doesn't erase what's there, it replaces it. For a a destructive backspace,
use "\b \b" i.e. a backspace, a space, and another backspace.
This Program prints all the prime number up to given number with comma separated

Can you explain this , challenge?

well let's see , i have this code of converting NFA automate to DFA ;which is written by me ; and i discovered let's say a "bug" ;
the printf() instruction
which is meant to be like this " printf("",X); " to prevent the bug
has no characters to print on the screen , you can use any argument you want ; even if it has no value .
the problem is when you remove one of these instructions the result turns upside down ( mingled displaying )
challenge is : explain this bug with details !
the bug is in the NFAtoDFA() func line 69 & 75
here's the code :
#include <stdio.h>
#include <string.h>
#define max 50 //maximum number of symbols and states
#define true 1
#define false 0
#define epsilon '~'
char states [max]={'0','1','2','3','4','5','6','7','8','9','W'};
char initState='0';
char symbols[max]={epsilon,'a','b'};
char finalStates[max]={'W'};
char newSymbols[max]={'a','b'};
char newStates[max][max];
int nbrSymbols=3,nbrStates=11,nbrNewStates=0,nbrNewSymbols=0,nfaMaxLength=2,dfaMaxLength=0;
char NFA [max] [max] [max];
char DFA [max] [max] [max];
int mm ;
/** NDAtoDFA of the NFA */
void NDAtoDFA();
char *makeDFAstate (char state[],int c);
char *epClosure (char stat);
char *nextStates (char sta,char symb);
void add_no_rpt (char ss[],char aa[]);
int getCharIndex (char str[],char c);
int accepted (char str[],char toAccept[]) ;
int findDfaState (char str[]);
/*******************************/
/** flag = 0 | 1 */
/** keep ( 0 | 1 ) occurrences of char c in a string */
void del(char str[],char c,int flag);
/******************************/
/** printing Automates */
void shift(int b,int a);
void showNFA();
void showDFA();
int isFinalState(char state[]);
/******************************/
int main()
{
strcpy( NFA[0][0],"17");strcpy( NFA[1][0],"24");strcpy( NFA[2][1],"3");strcpy( NFA[3][0],"6");
strcpy( NFA[4][2],"5");strcpy( NFA[5][0],"6");strcpy( NFA[6][0],"17");strcpy( NFA[7][1],"8");
strcpy( NFA[8][2],"9");strcpy( NFA[9][2],"W");
NDAtoDFA();
}
/******************************************************/
/******************************************************/
void NDAtoDFA()
{
int i,j; char zz[max];
strcpy(newSymbols,symbols); del(newSymbols,epsilon,0);
nbrNewSymbols=strlen(newSymbols);
/** making the first state*/
strcpy(newStates[nbrNewStates++], epClosure(initState) );
/** */
printf("",mm); /** <=== */
for(i=0;i<nbrNewStates;i++)
{
for(j=0;j<nbrNewSymbols;j++)
{
strcpy(DFA[i][j],makeDFAstate(newStates[i],j));
printf("",mm); /** <=== */
if(findDfaState(DFA[i][j])==false) {strcpy(newStates[nbrNewStates++],DFA[i][j]);
if(strlen(DFA[i][j])>dfaMaxLength) dfaMaxLength=strlen(DFA[i][j]);//for printing DFA
}
}
}
showNFA();
printf("\n ");shift(dfaMaxLength,0); printf("[][][]");
printf("\n ");shift(dfaMaxLength,0); printf("|| ||");
printf("\n ");shift(dfaMaxLength,0); printf("|| ||");
printf("\n ");shift(dfaMaxLength,0); printf("|| ||");
printf("\n ");shift(dfaMaxLength,0); printf("|| ||");
printf("\n ");shift(dfaMaxLength,2);printf("[][] [][]");
printf("\n ");shift(dfaMaxLength,2);printf(" \\\\ //");
printf("\n ");shift(dfaMaxLength,2);printf(" \\\\ // ");
printf("\n ");shift(dfaMaxLength,2);printf(" \\\\// ");
printf("\n ");shift(dfaMaxLength,2);printf(" \\/ ");
showDFA();
}
/******************************************************/
/******************************************************/
void add_no_rpt(char ss[],char aa[])
{int i,j;char tt[1];
for (i=0;aa[i]!=0;i++) if(getCharIndex(ss,aa[i])==-1) {tt[0]=aa[i];tt[1]=0;strcat(ss,tt);}
}
/******************************************************/
/******************************************************/
void del(char str[],char c,int flag)
{
char * p,*barrier;
barrier=p=strchr(str,c);
if (flag==1)
{
barrier=p+1; //set the barrier after the first occurrence of c
p=strchr(barrier,c);
}
while (p!=NULL)
{
for (;*p!='\0';p++) *p=*(p+1);
p=strchr(barrier,c);
}
}
/******************************************************/
/******************************************************/
char* nextStates (char sta,char symb)
{ int i,j;
for(i=0;i<nbrStates ;i++) if(sta ==states [i]) break;
for(j=0;j<nbrSymbols;j++) if(symb==symbols[j]) break;
return NFA[i][j];
}
/******************************************************/
/******************************************************/
int accepted (char str[],char toAccept[])
{ int i;
for (i = 0 ; toAccept[i]!=0; i++)
{
if(toAccept[i]==' ') {del(toAccept,toAccept[i],0);if(i!=0) i--;}
if(getCharIndex(symbols,toAccept[i])!=-1 || getCharIndex(str,toAccept[i])==-1) {return false;}
}
return true;
}
/******************************************************/
/******************************************************/
int getCharIndex(char str[],char c)
{
int i;
for (i = 0 ; str[i]!=0; i++) if(str[i]==c) return i;
return -1;
}
/******************************************************/
/******************************************************/
void showNFA()
{int i,j;
printf("\nSYMBOLS: %s\n",symbols);
printf("STATES : %s\n",states);
printf("FINAL STATES : %s\n\n",finalStates);
puts("STATE TRANS.");
printf("\n ");shift(dfaMaxLength+2,4);printf("NFA | ");
for (i = 0; i < nbrSymbols; i++) {printf(" %c", symbols[i]);shift(nfaMaxLength+1,0);}
printf("\n ");shift(dfaMaxLength+2,0);printf("--------");
for (i = 0; i < nbrSymbols; i++) for(j=0;j<nfaMaxLength+3;j++) printf("-"); printf("\n");
for (i = 0; i < nbrStates; i++) {
shift(dfaMaxLength+3,0);
printf(" %c | ",states[i]);
for (j = 0; j < nbrSymbols; j++)
{
if(strcmp(NFA[i][j],"")==0) {printf(" -");shift(nfaMaxLength+1,strlen(NFA[i][j]));}
else {printf(" %s",NFA[i][j]);shift(nfaMaxLength+2,strlen(NFA[i][j]));}
}
printf("\n");
}
}
/******************************************************/
/******************************************************/
void shift(int b,int a)
{int i;
for (i = 0; i < (b-a); i++)printf(" ");
}
/******************************************************/
/******************************************************/
void showDFA()
{int i,j;
printf("\n\n ");shift(dfaMaxLength,5);printf("DFA |");shift(5,0);
for (i = 0; i < nbrNewSymbols; i++) {printf("%c", newSymbols[i]);shift(dfaMaxLength+5,0);}
printf("\n ");for(j=0;j<dfaMaxLength+6;j++)printf("-");
for (i = 0; i < nbrNewSymbols; i++)for(j=0;j<dfaMaxLength+4;j++)printf("-"); printf("\n");
for (i = 0; i<nbrNewStates; i++) {
if (isFinalState(newStates[i])==true)
if (i==0) printf(" <-> ");
else printf(" <-- ");
else
if (i==0) printf(" --> ");
else printf(" ");
printf("{%s}",newStates[i]);shift(dfaMaxLength,strlen(newStates[i]));printf(" |");
for (j = 0; j < nbrNewSymbols; j++)
printf(" {%s} ",DFA[i][j]);
printf("\n");
}
}
/******************************************************/
/******************************************************/
char*epClosure(char stat)
{ int i,j;char zz[max];
zz[0] = stat; zz[1]=0;
for (i=0;zz[i]!=0;i++) add_no_rpt(zz,nextStates(zz[i],epsilon));
return zz;
}
/******************************************************/
/******************************************************/
int findDfaState(char str[])
{
int i;
for(i=0;i<nbrNewStates;i++)
{
if (accepted(newStates[i],str)==true && strlen(str)==strlen(newStates[i])) return true;
}
return false;
}
/******************************************************/
/******************************************************/
int isFinalState(char state[])
{
int i;
for(i=0;state[i]!=0;i++) if (strchr(finalStates,state[i])!=NULL) return true;
return false;
}
/******************************************************/
/******************************************************/
char *makeDFAstate(char state[],int c)
{
int i,j;char kk[max],yy[max];
for (i=0;state[i]!=0;i++)
{
add_no_rpt(kk,nextStates(state[i],newSymbols[c]));
j=strlen(kk)-1;
add_no_rpt(kk,epClosure(kk[j]));
}
return kk;
}
have fun !
You have 2 functions epClosure and makeDFAstate that return addresses to local variables. This is undefined behavior and a likely cause to your problem.
To fix it either dynamically allocate memory (using malloc) for the variables or take an address to write to as an argument e.g. void epClosure(char stat, char* buf). You'd probably want to also pass the size of the buffer to make sure you don't write past it.
puts(mm) yields undefined behavior, because mm does not point to a string.

How to use pointers to allocate an array inside another function

I'm 2nd year computer engineer and still in learning process of C language. I'd like to undesrtand how to dynamically alocate an array by using function instead of allocate inside the main.
Here is the code that works when I allocate array inside main.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#define ESC_KEY 27
#define NUM_1_KEY 49
#define NUM_2_KEY 50
void find_two_largest(int a[], int n, int *largest, int *second_largest);
void arrayInit(int *,int *, int, int);
void randGenArray(int [], int);
void inputArray(int[], int);
void result(int, int);
void loading(void);
int menu(void);
int main(void)
{
system("color f5");
int n,i,largest,largest_2, *a;
arrayInit(a,&n, 2, 10);
if(menu())
randGenArray(a,n);
else
inputArray(a,n);
find_two_largest(a,n,&largest,&largest_2);
result(largest,largest_2);
return 0;
}
void find_two_largest(int a[], int n, int *largest, int *second_largest)
{
int i=0,j=0;
system("cls");
loading();
*largest = 0;
*second_largest = *largest;
for (i=1;i<n;i++){
if(*largest<a[i])
*largest=a[i];
}
for(j=1;j<n;j++){
if(*largest==a[j])
continue;
else{
if(*second_largest<a[j])
*second_largest=a[j];
}
}
return;
}
void randGenArray(int a[], int n)
{
srand(time(NULL));
int i;
for(i=0; i<n; i++){
a[i]=rand()%100;
Sleep(10);
printf("\n>> Integer %d: %d", i+1, a[i]);
}
printf("\n\n\nPress any key to continue...");
getch();
return;
}
void inputArray(int a[], int n)
{
int i;
for(i=0; i<n; i++){
printf("\n Please enter integer %d: ", i+1);
scanf("%d",&a[i]);
}
return;
}
int menu(void)
{
char _char;
printf("\n Please choose one of the following options:\n 1.Fill array manually\n 2.Fill array by random numbers\n\n ");
while(1)
{
_char = getch();
switch(_char)
{
case ESC_KEY:
printf("\n\n Thank you for using our software!\n\n");
exit(0);
case NUM_1_KEY:
system("cls");
return 0;
case NUM_2_KEY:
system("cls");
return 1;
default:
break;
}
}
}
void arrayInit(int *a,int *n, int min, int max)
{
printf("\n Please enter a length of the array: ");
do{
scanf("%d", n);
if (*n<min||*n>max)
printf("\nThe ranged is limited. Please enter the value between %d and %d.\n", min, max);
} while(*n<min||*n>max);
a = (int*)calloc(*n,sizeof(int));
return;
}
void loading(void)
{
printf("\n Loading");
printf(".");
Sleep(300);
printf(".");
Sleep(300);
printf(".");
Sleep(300);
system("cls");
return;
}
void result(int l, int l2)
{
system("cls");
printf("\n Largest = %d Second Largest = %d",l,l2);
Sleep(500);
printf("\n\n\n Thank you using our software! ;D\n\n");
return;
}
But if you cut and paste this line from arrayInit to main and change *n to n - it will work!
a = (int*)calloc(*n,sizeof(int));
I'm sorry for asking about so stupid and obvious things but I didn't figure it out by myself. Thank you for any advice.
Here is a simple program which will show you how to do that -
#include <stdio.h>
#include <stdlib.h>
void create(int **p,int n); // function taking arguments as int ** and n is number of elements
int main(void) {
int *a;
int n=5,i; // declare and initialize n
create(&a,n); // pass address of a to function
for(i=0;i<n;i++){
a[i]=i; // store value of i in a[i]
printf("%d\n",i); // print a[i]
}
free(a); // free the allocated memory
return 0;
}
void create(int **p, int n){
*p=calloc(n,sizeof(int)); // allocate memory to *p (type- is int *)
}
Working Code
You must change your function return type
void * arrayInit(int *n, int min, int max)
{
printf("\n Please enter a length of the array: ");
do{
scanf("%d", n);
if (*n<min||*n>max)
printf("\nThe ranged is limited. Please enter the value between %d and %d.\n", min, max);
} while(*n<min||*n>max);
return calloc(*n,sizeof(int));
}
And call it from main in this way: a = arrayInit(&n, 2, 10);

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.

Memory can't be read when shortest function is run

I had a bunch of problems with this program but looks like this might be inches away from completion and I was hoping someone could tell me what the hell's wrong with the blasted thing!
#include <stdio.h>
#include <string.h>
#define SIZE_OF_STRING 21
void displayMenu(void);
void readArray(char [][SIZE_OF_STRING], int);
void printArray(char [][SIZE_OF_STRING], int);
int shortestArray(char [][SIZE_OF_STRING], int);
int smallestArray(char [][SIZE_OF_STRING], int);
void sortArray(char [][SIZE_OF_STRING], int);
int main(void)
{
int position, n = 0; /* all local to main */
char select[10]; /* select is a string */
char array[1000][SIZE_OF_STRING];
displayMenu();
scanf("%s", select); /* read first selection */
while (strcmp(select, "exit") != 0) /* while not exit */
{
if (strcmp(select, "read") == 0)
{
printf("How many names?");
scanf("%d", &n);
n++;
printf("Enter %d names", n - 1);
readArray(array, n);
}
else if (strcmp(select, "display") == 0)
{
printArray(array, n);
}
else if (strcmp(select, "shortest") == 0)
{
position = shortestArray(array, n);
printf("Shortest name is %s in position %d\n", array[position], position + 1);
}
else if (strcmp(select, "lowest") == 0)
{
position = smallestArray(array, n);
printf("Lowest name is %s in position %d\n",
array[position], position + 1);
}
else if (strcmp(select, "sort") == 0)
{
sortArray(array, n);
}
else
{
printf("INVALID SELECTION");
}
displayMenu();
scanf("%s", select); /* read next selection */
} /* end while */
}/* end main */
void displayMenu(void)
{
puts("Menu selection");
puts("Enter read to read names");
puts("Enter display to display names");
puts("Enter shortest for shortest name");
puts("Enter lowest for lowest names");
puts("Enter sort to sort names");
puts("Enter exit to exit\n");
}
void readArray(char a[][SIZE_OF_STRING], int n)
{
int i;
printf("\ntype one string per line\n");
for (i=0; i<n; i++)
{
gets(a[i]);
}
}
void printArray(char a[][SIZE_OF_STRING], int n)
{
int i;
printf("\ntype one string per line\n");
for (i=0; i<n; i++)
{
puts(a[i]);
}
}
int shortestArray(char a[][SIZE_OF_STRING], int n)
{
int i;
int chag = 0;
int position;
while (a[i] != '\0')
{
if (strlen(a[i]) < strlen(a[i-1]))
{
position = i;
chag = 1;
}
else
{
if (chag = 0)
{
position = 1;
}
else
{
printf("");
}
}
}
return position;
}
int smallestArray(char a[][SIZE_OF_STRING], int n)
{
puts("Not yet implemented\n");
return 0;
}
void sortArray(char a[][SIZE_OF_STRING], int n)
{
puts("Not yet implemented\n");
}
only worried about "shortest" function at the moment all others run okay.
I also know there are better ways of doing the search but I keep getting "declaration creates integer from pointer without cast" errors when I change to a more standard search with a default smallest etc.
chag is to say whether or not number one in a[] is the smallest as it never gets checked, going to change this as soon as I get it working as I can see a more effective way of doing it.
[edit]
My bad, the error that appears is an application error when "smallest" is selected.
the following appears
"the instruction at "0x77c478c0" referenced memory at "0xd2fd82e0". the memory could not be "read".
ok to terminate program, cancel to debug.
changed the shortest function to the following and still get a similar memory message;
int shortestArray(char a[][SIZE_OF_STRING], int n)
{
int i = 1;
int position = 1;
while (a[i] != '\0')
{
if (strlen(a[i + 1]) < strlen(a[i]))
{
position = i + 1;
i++;
}
else
{
i++;
}
}
return position;
}
There's a clbuttic typo in shortestArray():
if (chag = 0) {
position = 1;
}
// ...
This will always evaluate to false, so the else block is run.
Here, zero is assigned to chag which makes the expression evaluate to zero (false). Use the comparision operator == instead. You might want to crank up warning levels as I'm sure, any C compiler has an appropriate message for this.
One big and obvious problem is that in the function you use the variable i without initializing it.
Another problem is this expression: strlen(a[i-1]). If i is 0 then this will access memory before the array.
In addition to the other answers so far:
You don't increment i either.
If I imagine all the trivial fixes applied (correct iteration, comparison instead of assignment in the condition), the function is going to return position of last local minimum of length. I.e. having list of strings like
"a", "bbbb", "ccc", "dd"
it will return 3, but shortest string is at position 0!
You do remember array indices in C start from 0, right (in position = 1)?
you have to know the number of strings entered in the array to avoid unknown behavior.
a way to do this : in main, just after declaration of array, put :
strcpy(array[0], ""); // to indicate that the array is empty.
in the end of readArray() :
strcpy(a[n] , ""); // there is n strings written bythe user (a[0] to a[n-1]).
and finally :
in shortestArray(), the stop condition of the loop must be changed to :
while (strcmp(a[i],"") != 0 ) //a[i] == '\0' is not correct because a[i] is string and '\0' is char.
here is the entire code with the changes i made :
#include <stdio.h>
#include <string.h>
#define SIZE_OF_STRING 21
#define SIZE_OF_ARRAY 1000
void displayMenu(void);
void readArray(char [][SIZE_OF_STRING], int);
void printArray(char [][SIZE_OF_STRING]);
int shortestArray(char [][SIZE_OF_STRING]);
int smallestArray(char [][SIZE_OF_STRING], int);
void sortArray(char [][SIZE_OF_STRING], int);
int main(void)
{
int position, n = 0; /* all local to main */
char select[10]; /* select is a string */
char array[SIZE_OF_ARRAY][SIZE_OF_STRING]; //change here !
strcpy(array[0] , ""); //instruction added : means array is empty
displayMenu();
scanf("%s", select); /* read first selection */
while (strcmp(select, "exit") != 0) /* while not exit */
{
if (strcmp(select, "read") == 0)
{
printf("How many names?");
scanf("%d", &n);
while (n >= SIZE_OF_ARRAY)
{
printf("the number you entered is bigger than the maximum number of strings, please enter a number smaller than %d\n", SIZE_OF_ARRAY);
}
printf("Enter %d names", n);
readArray(array, n);
}
else if (strcmp(select, "display") == 0)
{
printArray(array);
}
else if (strcmp(select, "shortest") == 0)
{
position = shortestArray(array);
if (position == -1)
printf("there is no string entered !\n");
else
printf("Shortest name is %s in position %d\n", array[position-1], position );
}
else if (strcmp(select, "lowest") == 0)
{
position = smallestArray(array, n);
printf("Lowest name is %s in position %d\n",
array[position], position + 1);
}
else if (strcmp(select, "sort") == 0)
{
sortArray(array, n);
}
else
{
printf("INVALID SELECTION");
}
displayMenu();
scanf("%s", select); /* read next selection */
} /* end while */
}/* end main */
void displayMenu(void)
{
puts("Menu selection");
puts("Enter read to read names");
puts("Enter display to display names");
puts("Enter shortest for shortest name");
puts("Enter lowest for lowest names");
puts("Enter sort to sort names");
puts("Enter exit to exit\n");
}
void readArray(char a[][SIZE_OF_STRING], int n)
{
int i;
printf("\ntype one string per line\n");
for (i=0; i<n; i++)
{
scanf("%s",a[i]);
}
strcpy(a[n] , "");
}
void printArray(char a[][SIZE_OF_STRING])
{
int i;
for (i=0; i< SIZE_OF_ARRAY; i++)
{
if (strcmp(a[i] , "") == 0) // a[i-1] is last string entered
break; // this avoid printing non initialized string causing unknown behaviour.
printf("%s\n",a[i]);
}
}
int shortestArray(char a[][SIZE_OF_STRING])
{
int i = 0;
int position = 1;
if(strcmp (a[i] , "\0") == 0)
return position = -1; // there no string entered.
while (strcmp (a[i+1] , "\0") != 0)
{
if (strlen(a[i+1]) < strlen(a[i]))
{
position = i+2 ;
i++;
}
else
{
i++;
}
}
return position;
}
int smallestArray(char a[][SIZE_OF_STRING], int n)
{
puts("Not yet implemented\n");
return 0;
}
void sortArray(char a[][SIZE_OF_STRING], int n)
{
puts("Not yet implemented\n");
}

Resources