How to make this program considered as a recursive rfunciton - c

I have created the program that functionally works the way it is supposed to but I have to make it recursive and I was told that function void expand() is not considered as a recursive function. Any tips?
#include <stdio.h>
#include <string.h>
#define max_size 300
int main(){
char defstr[max_size]="The universe is ever expanding!";
int num, buff_num;
printf("Input how much to expand: ");
scanf("%d",&num);
buff_num=num;
expand(defstr, num, 0, 0);
return 0;
}
void expand(char str[max_size], int n, int dash, int i){
if(n>-1){
if(str[i+1]!='\0'){
printf("%c",str[i]);
for(int j=dash; j>0; j--)
printf("-");
expand(str, n, dash, i+1);
}
else if(str[i+1]=='\0'){
printf("%c", str[i]);
printf("\n");
expand(str, n-1, dash+1, 0);
}
}
}
The program is built to output this type of text depending on the user input of how many dashes.
T-h-e- -u-n-i-v-e-r-s-e- -i-s- -e-v-e-r- -e-x-p-a-n-d-i-n-g-!
T--h--e-- --u--n--i--v--e--r--s--e-- --i--s-- --e--v--e--r-- --e--x--p--a--n--d--i--n--g--!
T---h---e--- ---u---n---i---v---e---r---s---e--- ---i---s--- ---e---v---e---r--- ---e---x---p---a---n---d---i---n---g---!

It is a recursive function in that it calls itself. However, my guess is that is is supposed to print the entire string with dashes each time.
void expand(char *str, int num_dashes)
{
// End recursion
if (num_dashes < 0) return;
// Call recursively
expand(str, num_dashes - 1);
// Print entire string with dashes
for (int i = 0; str[i]; i++) {
if (i != 0) {
for (int j = 0; j < num_dashes; j++) {
fputc('-', stdout);
}
}
fputc(str[i], stdout);
}
puts("");
}

Related

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.

I don't see why this doesn't work

The goal of this code was to print a pyramid. First I print a certain number of spaces then print some stars to eventually make a pyramid.
For example to print a pyramid of 5 first it would print a star after 4 spaces then the start and end variables would be changed so the new start would 3 and the new end would be six and it would print 3 stars.
#include <stdio.h>
#include <stdlib.h>
void printSpaces(int num){
int i;
for(i=0; i<num;i++)
{
printf(" ");
}
}
void pyramid(int n){
int start=n,end=n+1;
int k;
while(start>0 && end<2*n)
{
printSpaces(start);
for (k=start; k<end;k++)
{
printf("*");
}
printf("\n");
start=n-1;
end=n+1;
}
}
int main(void) {
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
pyramid(5);
return 0;
}
The only thing it seems to be doing printing a row of 2 stars over and over.
you set start to n-1, but the value of n never changes. That means that start will continuously be set to the same value, n-1(4). Same for end, your loop will never terminate.
void pyramid(int n){
int start=n,end=n+1;
int k;
while(start>0 && end<2*n)
{
printSpaces(start);
for (k=start; k<end;k++)
{
printf("*");
}
printf("\n");
start=n-1;
end=n+1;
}
}
Also, on first invocation, k will be 4 and end will be 6, hence two stars.
Your problem is right here:
start=n-1;
end=n+1;
it should be something like start = start + 1 ?
I don't understand your program perfectly but I can tell that this is your error.
Matt McNabb was very close.
The following code contains the correct fix
The main change is to step 'start' and 'end' rather than re-initializing them to the passed parameter
#include <stdio.h>
#include <stdlib.h>
void printSpaces(int num){
int i;
for(i=0; i<num;i++)
{
printf(" ");
}
}
void pyramid(int n){
int start=n,end=n+1;
int k;
while(start>0 && end<2*n)
{
printSpaces(start);
for (k=start; k<end;k++)
{
printf("*");
}
printf("\n");
start--; //<< corrected
end++; //<< corrected
}
}
int main(void) {
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
pyramid(5);
return 0;
}
the procedure that you are using to decrement the value of the variables end and start are wrong
I found this code about patterns in c in this site
http://www.programmingsimplified.com/c-program-print-stars-pyramid
#include <stdio.h>
#include <stdlib.h>
void pyramid(int end){
int k,c;
for (k=1; k< end; k++) {
printf(" ");
end= end -1;
for (c=1; c<= 2 * k-1; c++)
printf("*");
printf("\n");
}
}
int main() {
pyramid(15);
return 0;
}

Drawing a triangle with one loop (Revised)

The triangle should look like this
1
11
111
1111
11111
111111
the number of rows is entered by the user and then transforms to the function
Note: Without arrays, must be with one loop(while or for) and not nested loops
the closest I got is a code with 2 loop (but can`t think about how to do it with less loops)
int i,k;
for(i=1;i<=x;i++)
{
for(k=1;k<=i;k++)
{
printf("1");
}
printf("\n");
}
The above question was asked by someone but it was marked as off topic I don't know why..?
I came up with this solution tell me if it's correct or not?
int i=1,k=1;
while (i<=x)
{
if(k<=i)
{
printf("1");
k++;
continue;
}
i++;
k=1;
printf("\n");
}
thanks
You can replace loops(iteration) with recursion, try this(with one loop):
#include <stdio.h>
void draw(int depth)
{
int i;
if(depth <= 0) return;
draw(depth-1);
for(i = 0; i < depth; i++)
printf("1");
printf("\n");
}
int main()
{
draw(5);
return 0;
}
You can do it even without loop
#include <stdio.h>
void draw_num_char(int num)
{
if(num <= 0) return;
printf("1");
draw_num_char(num-1);
}
void draw(int depth)
{
int i;
if(depth <= 0) return;
draw(depth-1);
draw_num_char(depth);
printf("\n");
}
int main()
{
draw(5);
return 0;
}
Recursive solution, one loop, no arrays.
#include <stdio.h>
void liner(int line, int limit) {
int i;
if (line > limit)
return;
for(i=1; i<=line; i++)
printf("1");
printf("\n");
liner (line + 1, limit);
}
int main() {
int limit;
printf ("Enter number of lines ");
scanf ("%d", &limit);
liner (1, limit);
return 0;
}

printing a 2d array of string in c

i'm trying to print a 2d array of string as practice(i'm a newbie) with no success i've tried every combination i could think of still nothing i'm sure i'm doing a silly error somewhere i just can't see it here some of the example:
using a pointer :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lim 10
#define maxx 25
void print(char *);
int main()
{
int i = 1;
char input[lim][maxx];
char *ps = input;
printf("type the list of %d names or type quit to leave \n", lim);
while (i<lim && gets(input[i]) != NULL && strncmp(input[i], "quit", 4)!=0 ) {
i++;
}
printf("i've counted %d names\n", i);
print("\n");
print(ps);
return 0;
}
void print(char *a)
{
int i=0;
printf("the list of names include : \n");
while(*(a) != '\0') {
printf("%s\n", *(a+i));
i++;
}
}
here's the output:
type a list of %d names or type quit to leave :
bla
bli
blo
quit
i've counted 4 names
the list of names include :
segmentation fault (core duped)
another version of the print function is like this :
void print(char aray[lim][maxx])
{
int i,j;
printf("the list of names include : \n");
for(i = 0; i < lim; i++) {
for(j = 0; j < maxx; j++){
puts(aray[i][j]);
//printf("%s\n", aray[i][j]);
}
}
}
i get the same output, can anyone help me debug this ? and thx in advance
In short, it looks like you need to brush up on your pointers. With your original print function:
void print(char *a)
{
int i=0;
printf("the list of names include : \n");
while(*(a) != '\0') {
printf("%s\n", *(a+i));
i++;
}
}
You are printing the value at a + i every iteration. This might sound like what you want, but what you actually pass to print is a pointer to an array of arrays of char (your compiler should be throwing a warning about incompatible pointer types). That is, the "proper" type of ps is (char *)[]. So in the print function you are only advancing the memory address by sizeof(char) with each iteration, whereas what you actually want is to increment it by sizeof(char) * maxx (the size of your array entries). To implement this change, do the following:
change declaration of print
void print(char (*)[maxx]);
change to proper pointer type
char (*ps)[maxx] = input;
And finally, change print function to something like:
void print(char (*a)[maxx]){
printf("the list of names include : \n");
int i;
for (i = 0; i < lim; i++){
printf("%s\n",*a);
a++;
}
}
You need not use the (a+i) syntax, as just advancing a by one each iteration accomplishes the same thing, and is possibly faster for large i. And of course, as others have mentioned, double check your new line printing, I believe you want printf('\n').
You are adding i as 1 which will not help in case of your two dimensional array as the next element will be at maxx location,so you can do something like this
//here lim and max are defined in your program
void print(char *a){
int i=0;
printf("the list of names include : \n");
while(i<(lim*maxx)){
printf("%s\n",a );
i += maxx;
a = a + maxx;
}
}
and the second variant should be
void print(char aray[lim][maxx])
{
int i,j;
printf("the list of names include : \n");
for(i = 0; i < lim; i++) {
cout<<aray[i]<<"\n";
}
}
You start on index 1 in your 2d array, you should start with index 0
int i=1;
Your print function takes an array of characters and then does a printf string of each character which makes no sense
void print(char *a)
{
int i=0;
printf("the list of names include : \n");
while(*(a)!='\0')
{
printf("%s\n",*(a+i));
i++;
}
}
instead make it look like this
void print(char *a[], int strings)
{
int i = 0;
for (; i < strings; ++i)
{
puts( a[i] );
}
}
and call it with the number of strings you read
print(ps,i);
You would also be better off using fgets() instead of gets(), especially since your strings are max 25 chars so its easy to give a longer string. fgets() lets you specify the max size of the string fgets(input[i],maxx,stdin)
Your other function
void print(char aray[lim][maxx])
{
int i,j;
printf("the list of names include : \n");
for(i = 0; i < lim; i++) {
for(j = 0; j < maxx; j++){
puts(aray[i][j]);
//printf("%s\n", aray[i][j]);
}
}
}
does a similar wrong assumption about the level of indirection
arra[i][j] is one character but puts takes a string argument, so puts( arra[i][j] ); is not correct, you could try fputc( arra[i][j], stdout ) instead since fputc takes one character
fix to
void print(char (*)[maxx]);
int main()
{
int i = 0;//int i = 1;
char input[lim][maxx] = { {'\0'}};
char (*ps)[maxx] = input;
printf("type the list of %d names or type quit to leave \n", lim);
while (i<lim && gets(input[i]) != NULL && strncmp(input[i], "quit", 4)!=0 ) {
i++;
}
printf("i've counted %d names\n", i);
printf("\n");//print("\n");
print(ps);
return 0;
}
void print(char (*a)[maxx])
{
int i=0;
printf("the list of names include : \n");
while(i<lim && a[i][0] != '\0') {
printf("%s\n", a[i]);
i++;
}
}

read input character and print the occurrence in graphical format

I am reading the input and trying to print all the input lowercase character in a graphical format, am able to read it and keep track of the number of time each character repeats but not able to print it in a graphical way,can u pls help me out. Here is my code
#include <stdio.h>
#include <ctype.h>
int print_fun(int);
int main() {
int ch = 0, i = 0;
int char_count[26] = {0};
printf("\nNOTE:PRESS * TO EXIT\n");
while((ch = getchar()) != '*') {
if(islower(ch))
char_count[ch - 'a']++;
}
printf("\n");
for(i = 0; i < 26; i++)
//printf("%c:%d\n",'a'+ i, char_count[i]);
//printf("%c:\n", 'a'+ i, print_star(char_count[i]));
printf("%c:\n",print_star(char_count[i]),'a'+ i);
printf("\n");
return 0;
}
int print_star(int value) {
int i = 0;
for(i = 0; i < value; i++)
printf("*");
}
o/p: aaxyyz
a:**
b:
c:
...
...
x:*
y:**
z:*
Your printf call is missing an format argument, you have this:
printf("%d:%c\n",print_star(char_count[i]),'a'+ i);
but you are passing two arguments to printf, as far as I can tell this is what you meant:
printf("%d:%c\n",print_star(char_count[i]),'a'+ i);
Also, print_star has a return value of int but you do not have a return statement, I think you meant to return i and in that case you should add:
return i ;
at the end. The behavior without a return at the end is undefined. Finally, it looks like you have a typo in forward declaration, this:
int print_fun(int);
should be:
int print_star(int value );
#include <stdio.h>
#include <ctype.h>
//int print_fun(int);
void print_star(int);
int main(void){
int ch = 0, i = 0;
int char_count[26] = {0};
printf("\nNOTE:PRESS * TO EXIT\n");
while((ch = getchar()) != '*'){
if(islower(ch))
char_count[ch - 'a']++;
}
printf("\n");
for(i = 0; i < 26; i++){
printf("%c:",'a'+ i);
print_star(char_count[i]);
printf("\n");
}
printf("\n");
return 0;
}
void print_star(int value){
int i = 0;
for(i = 0; i < value; i++)
printf("*");
}

Resources