My C program is recursing infinitely and I cannot figure out why - c

This program is supposed to take a name from a user and output it backwards. Our professor said we had to use recursion and I am struggling with getting to not recurse infinitely. Please help.
#include <stdio.h>
#include <string.h>
void reversedWord(char input[],int size)
{ int count;
int count2;
if(count==0) {
count2=size;
}
count2=count2-1;
char store;
store=input[count2];
input[count2]=input[count];
input[count]=store;
count=count+1;
if(count>size)
{
return;
}
return reversedWord(input,size);
}
int main()
{
char input[100];
printf("Please enter your name: ");
scanf("%s",input);
int size=strlen(input);
reversedWord(input,size);
printf("\n Your name backwards: %s \n",input);
}

First in the above code, you need to initialize your variables count and count2.
The statements int count; means that you are declaring the variable count of integer type. But it doesn't hold any value.
for this example to have the recursion working, you need to pass 3 parameters(input string, start_index,end_index) at each call to the function.
Here's the modified code to have this working
void reversedWord(char input[],int start,int end)
{
end=end-1;
char store;
store=input[end];
input[end]=input[start];
input[start]=store;
start=start+1;
if(start>=end)
{
return;
}
return reversedWord(input,start,end);
}
int main()
{
char input[100];
printf("Please enter your name: ");
scanf("%s",input);
int size=strlen(input);
reversedWord(input,0,size);
printf("\n Your name backwards: %s \n",input);
}

Since you use counters inside your recursive function they should be static, I suggest reading documentation about what static does in the C language if it is new to you.
Below is your code with working recursion, but your algorithm for word reversion contains an error. I believe you can solve it yourself with a bit of thought, so I will just give a hint - it reverses the word, but then reverses it back right again.
#include<stdio.h>
#include<string.h>
void reversedWord(char input[],int size)
{
static int count = 0;
static int count2;
if(count==0) {
count2=size;
}
count2=count2-1;
char store;
store=input[count2];
input[count2]=input[count];
input[count]=store;
count=count+1;
if(count>size)
{
return;
}
reversedWord(input,size);
return;
}
int main()
{
char input[100];
printf("Please enter your name: ");
scanf("%s",input);
int size=strlen(input);
reversedWord(input,size);
printf("\n Your name backwards: %s \n",input);
}

I think even if you assign zero to count and count2 ,this will not work because you are calling the function recursively.
So every time you call reversedWord(input,size) the values are again initialized;
> void reversedWord(char input[],int size) { int count; //initialized
> for every recursive call
> int count2; //initialized for every recursive call
> if(count==0) {
> count2=size;
> }
> count2=count2-1;
> char store;
> store=input[count2];
> input[count2]=input[count];
> input[count]=store;
> count=count+1;
> if(count>size)
> {
> return;
> }
> return reversedWord(input,size); }
A better solution would be to declare these two variables count and count2 as static.
static int count,count2 ;
by default the static variable are assigned as 0 and they share a common memory,so no new space is assigned to them and the new values get reflected on the same variable(initialized just once)

Related

Structure printf stops the program from working

I created the following code, it compiles but it doesen't run properly. It shows some imput witch is correct, but after that, instead of printing according to the line printf(prod[0].dr[0]); it enters an "not responding" state. If you instead write printf(prod[0].dr); it works perfectly. I need to be able to print each character individualy (so I need something like printf(prod[0].dr[0]); that works)
If the question is to broad, please comment and I will try to specify every detail.
Thanks!
#include <stdio.h>
FILE *f, *g;
struct productie
{
char st, dr[20];
int realizabil;
}prod[30];
int citire(FILE *f){
char sir[100];
int i=0,j;
while(!feof(f))
{
fgets(sir,100,f);
prod[i].st=sir[0];
for(j=3;j<strlen(sir);j++)
prod[i].dr[j-3]=sir[j];
i++;
}
return i;
}
int exista(char sir[],char c)
{
int i;
for(i=0;i<strlen(sir);i++)
{
if(c==sir[i])
return 1;
}
return 0;
}
void neterminale(struct productie p[],int n, char N[])
{
int k=0;
int i,j;
for(i=0;i<n;i++)
{
if(isupper(p[i].st) && !exista(N,p[i].st))
N[k++]=p[i].st;
for(j=0;j<strlen(p[i].dr);j++)
if(isupper(p[i].dr[j]) && !exista(N,p[i].dr[j]))
N[k++]=p[i].dr[j];
}
N[k]='\0';
}
void terminale(struct productie p[],int n, char T[],char N[])
{
int k=0;
int i,j;
for(i=0;i<n;i++)
{
if(!exista(N,p[i].st) && !exista(T,p[i].st)&& p[i].st!='$')
T[k++]=p[i].st;
for(j=0;j<strlen(p[i].dr);j++)
if(!exista(N,p[i].dr[j]) && !exista(T,p[i].dr[j]) && p[i].dr[j]!='$')
T[k++] = p[i].dr[j];
}
T[k]='\0';
}
void afisare(FILE *g,int n){
int i;
for(i=0;i<n;i++)
fprintf(g,"%c -> %s",prod[i].st, prod[i].dr);
}
int main(){
char N[30];
char T[30];
int i,j,n;
f=fopen("in.txt","r");
n=citire(f);
neterminale(prod,n,N);
printf("\nNeterminalele sunt:{");
for(i=0;i<strlen(N);i++)
printf("%c ",N[i]);
printf("}");
terminale(prod,n,T,N);
printf("\nTerminalele sunt:{");
for(i=0;i<strlen(T);i++)
{
printf(" %c ",T[i]);
}
printf("}");
printf(prod[0].dr[0]); //AT THIS LINE IS THE PROBLEM
g=fopen("out.txt","w");
afisare(g,n);
fclose(f);
fclose(g);
return 0;
}
The in.txt :
S->aS
S->a
S->$
S->AB
A->b
B->c
If you want to print a string directly, you need to provide a pointer to the first character, not the first character itself:
printf(&(prod[0].dr[0]));
or
printf(prod[0].dr);
But you can't limit this to a single char (there is no nprintf function).

How to create multiple functions in C

I am new to C programming and I am trying to create functions. The first function executes but the second one doesn't.
#include <stdio.h>
char get_char();
int main(void)
{
char ch;
printf("Enter a character > ");
scanf("%c", &ch);
return ch;
}
int get_int()
{
int i;
printf("Enter an integer between 0 and 127 > ");
scanf("%d", &i);
return i;
}
For anyone else that arrives here, you may solve your problem, by making sure your main function is at the bottom of the file.
Why? Because if function a calls function b, a should be before b.
main is the entry point for your program. The C environment calls main when your program is executed. get_int() is not the name for an entry point, so the fact that you never call it directly or indirectly in main means it will never be executed.
You also didn't declare it before main meaning your compiler will warn about not finding it, but since get_int returns int it will link successfully regardless.
Fix:
int get_int();
int main ()
{
//...
}
int get_int()
{
//...
}
Your second function isn't called and it should be as follows:
int main()
{
int m = 10;
get_int(m);
return 0;
}
int get(int num)
{
int multiply = num * num;
return multiply;
}

Am I using structs in the wrong way?

I have come across this wierd and mysterous (at least to me) error that I am finding a very hard time finding. It gives me an error at the line where I call my function input(student_list1[MAX], &total_entries); where the compiler says:
incompatible type for agument 1 in 'input'
What am I doing wrong here? I sense it something very simple and stupid but I have gone through the code several times now without any avail.
#define MAX 10
#define NAME_LEN 15
struct person {
char name[NAME_LEN+1];
int age;
};
void input(struct person student_list1[MAX], int *total_entries);
int main(void)
{
struct person student_list1[MAX];
int total_entries=0, i;
input(student_list1[MAX], &total_entries);
for(i=0; i<total_entries; i++)
{
printf("Student 1:\tNamn: %s.\tAge: %s.\n", student_list1[i].name, student_list1[i].age);
}
return 0;
} //main end
void input(struct person student_list1[MAX], int *total_entries)
{
int done=0;
while(done!=1)
{
int i=0;
printf("Name of student: ");
fgets(student_list1[i].name, strlen(student_list1[i].name), stdin);
student_list1[i].name[strlen(student_list1[i].name)-1]=0;
if(student_list1[i].name==0) {
done=1;
}
else {
printf("Age of student: ");
scanf("%d", student_list1[i].age);
*total_entries++;
i++;
}
}
}
struct person student_list1[MAX] in the function argument is actually a pointer to struct person student_list1.
student_list1[MAX] you passed is a (out of bound) member of the array struct person student_list1[MAX]. Valid array index shoudl be between 0 to MAX - 1.
Change it to:
input(student_list1, &total_entries);
Note that here the array name student_list1 is automatically converted to a pointer to student_list1[0].
There are many things wrong with the code; this is my attempt at making it somewhat more robust:
#include <stdio.h>
#include <string.h>
#define MAX 10
#define NAME_LEN 15
// use a typedef to simplify code
typedef struct person {
char name[NAME_LEN];
int age;
} person_t;
// size qualifier on student_list is redundent and person_t* does the same
void input(person_t *student_list, int *total_entries);
int main(void)
{
person_t student_list[MAX];
int total_entries, i;
// pass array and not the non-existent 'student_list[MAX]' element
input(student_list, &total_entries);
for(i=0; i<total_entries; i++)
{
// age is an int, not a string so use %d
printf("Student 1:\tName: %s.\tAge: %d.\n", student_list[i].name, student_list[i].age);
}
return 0;
} //main end
void input(person_t *student_list, int *total_entries)
{
int done = 0, i = 0;
*total_entries = 0;
while (i < MAX) {
printf("Name of student: ");
// use NAME_LEN instead of strlen(list[i].name) because latter is
// probably not initialized at this stage
if (fgets(student_list[i].name, NAME_LEN, stdin) == NULL) {
return;
}
// detect zero-length string
if (student_list[i].name[0] == '\n') {
return;
}
printf("Age of student: ");
scanf("%d", &student_list[i].age);
// read the newline
fgetc(stdin);
*total_entries = ++i;
}
}
input(student_list1[MAX], &total_entries); shoud be input(student_list1, &total_entries);.
In C,
void input(struct person student_list1[MAX], int *total_entries);
equals
void input(struct person *student_list1, int *total_entries);

Segmentation fault when copying string to

Hit there!
Below is a little program I made today. It takes a table of strings, reverses all strings without reversing table, then sorts those reversed string, then reverses them back, and at last prints whole table.
I was trying really long to figure out why can't I copy 'slowo' string into place in table pointed in strcmp, but with no success. I would be happy if someone would find a way to fix Segmentation Fault in this case, but I really want to leave the method as it is below.
Thanks for your help! :)
EDIT By using debugger I determined that Segmentation Fault appears in strcpy, if that wasn't clear...
#include <stdio.h>
#include <string.h>
const int ROZMIAR=4;
char* nieposortowane[]={"basia", "zosia", "ala", "genowefa"};
int porownaj(char* a, char* b)
{
return strcmp(a,b);
}
void sortowanie(char** tablica, int N)
{
int zamienione, i;
char tmp;
do
{
zamienione=0;
for(i=0;i<N-1;i++)
if(porownaj(nieposortowane[i], nieposortowane[i+1])>0)
{
tmp=**(tablica+i);
**(tablica+i)=**(tablica+(i+1));
**(tablica+(i+1))=tmp;
zamienione=1;
}
}
while(zamienione);
}
void wypisz(char** tablica, int N)
{
int i=0;
for(i=0;i<N;i++)
printf("%s\n", *(tablica+i));
}
void odwr(char** tablica, int N)
{
int i, ln, c;
int start, koniec;
char temp;
for(i=0;i<N;i++)
{
ln = strlen(tablica[i]);
char slowo[ln];
strcpy(slowo,*(tablica+i));
start=0;
koniec=ln-1;
for(c=0;c<(ln/2);c++)
{
temp =slowo[start];
slowo[start]=slowo[koniec];
slowo[koniec]=temp;
start++;
koniec--;
}
strcpy(*(tablica+i), slowo);
}
}
int main()
{
printf("Przed sortowaniem: \n");
wypisz(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
sortowanie(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
printf("Po sortowaniu babelkowym: \n");
wypisz(nieposortowane, ROZMIAR);
return 0;
}
When allocating slowo, you should add 1 to the result of strlen when calculating the size to allocate. This is to accomodate the terminating null character, which is not included in a string's length (returned by strlen), but must be included in its total allocated size.
AFAICS, you are trying to modify the strings in:
char* nieposortowane[]={"basia", "zosia", "ala", "genowefa"};
Those are string literals stored in read-only memory; any attempt to modify them (for example, by reversing them) will fail.
I reproduced the crash with your original code. This revision of the code doesn't crash; it goes into an infinite loop in your sort code instead. I've not debugged that part of your code.
#include <stdio.h>
#include <string.h>
const int ROZMIAR=4;
char basia[] = "basia";
char zosia[] = "zosia";
char ala[] = "ala";
char genowefa[] = "genowefa";
char* nieposortowane[]={basia, zosia, ala, genowefa};
int porownaj(char* a, char* b)
{
return strcmp(a,b);
}
void sortowanie(char** tablica, int N)
{
int zamienione, i;
char tmp;
do
{
zamienione=0;
for(i=0;i<N-1;i++)
if(porownaj(nieposortowane[i], nieposortowane[i+1])>0)
{
tmp=**(tablica+i);
**(tablica+i)=**(tablica+(i+1));
**(tablica+(i+1))=tmp;
zamienione=1;
}
}
while(zamienione);
}
void wypisz(char** tablica, int N)
{
int i=0;
for(i=0;i<N;i++)
printf("%s\n", *(tablica+i));
}
void odwr(char** tablica, int N)
{
int i, ln, c;
int start, koniec;
char temp;
for(i=0;i<N;i++)
{
ln = strlen(tablica[i]);
char slowo[ln];
strcpy(slowo,*(tablica+i));
start=0;
koniec=ln-1;
for(c=0;c<(ln/2);c++)
{
temp =slowo[start];
slowo[start]=slowo[koniec];
slowo[koniec]=temp;
start++;
koniec--;
}
strcpy(*(tablica+i), slowo);
}
}
int main()
{
printf("Przed sortowaniem: \n");
wypisz(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);
sortowanie(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);
printf("Po sortowaniu babelkowym: \n");
wypisz(nieposortowane, ROZMIAR);
return 0;
}
Sample output:
Przed sortowaniem:
basia
zosia
ala
genowefa
aisab
aisoz
ala
afewoneg
I had to interrupt after that, but you can see that the strings are reversed successfully.
You'll need to sort out a more general solution; naming the individual arrays as I did is easy for a small fixed set, but not generally. One possibility would be to use strdup() to duplicate each string into allocated space:
enum { SIZE_NPSW = sizeof(nieposortowane) / sizeof(nieposortowane[0] };
for (i = 0; i < SIZE_NPSW; i++)
nieposortowane[i] = strdup(nieposortowane[i]);

Can printf change one of its parameters that is an array?

Here is my code:
#define MAX_SET_LENGTH 255
typedef struct{
char name;
char *elemetns;
}Set;
void createSet();
int getString();
void filter(char raw[],int *length);
void menu();
void del_duplicate(char *s,int n);
void displyAllSets();
Set sets[26];
int setCount=0;
int main(){
menu();
}
void menu(){
int input;
do{
printf("\n1.Create Set.\n");
printf("2.display all Sets.\n");
printf("0.Exit.\n");
scanf("%d",&input);
switch(input){
case 0:
break;
case 1:
createSet();
break;
case 2:
displyAllSets();
break;
default:
printf("Error input,please input again\n");
}
}while (input!=0);
}
void displyAllSets(){
int i;
for(i=0; i<setCount; i++) {
printf("\n%c->{%s}\n",sets[i].name,sets[i].elemetns);
}
}
void createSet(){
if(setCount<26){
printf("Please input the set's elements:\n");
char elements[MAX_SET_LENGTH];
int s_length = getString(elements,MAX_SET_LENGTH);
filter(elements,&s_length);
del_duplicate(elements,s_length);
if(s_length > 0){
elements[s_length]='\0';
Set set;
set.elemetns = elements;
set.name = 'a'+ setCount;
sets[setCount++]=set;
displyAllSets();
}else{
printf("No illegal input!\n");
}
}else{
printf("It's limit to 26");
}
}
int getString(char s[],int max_length){
char c;
int i=0;
getchar();
while((c=getchar())!='\n')
s[i++]=c;
return (i>=max_length ? max_length : i);
}
void filter(char raw[],int *length){
char string[*length];
int i=0,j=0;
int deletedCount=0;
for(;i<*length;i++){
string[i]=raw[i];
}
for(i=0;i<*length;i++){
if(string[i]>='A' && string[i]<='Z'){
raw[j++]=string[i];
}else{
deletedCount++;
}
}
*length-=deletedCount;
raw[j]='\0';
}
void del_duplicate(char raw[],int length){
int i=0,j;
for(;i<length && length>0;i++){
for(j=i+1;j<length;){
if(raw[i]==raw[j]){
int delFrom=j;
while(delFrom<length){
raw[delFrom]=raw[delFrom+1];
delFrom++;
}
j=i+1;
length--;
}else{
j++;
}
}
}
}
Everything looks good when calling createSet();
but, after calling printf("\n1.Create Set.\n") in do-while block, the array sets has been modified. Can anyone help?
after pressing F6
Can you see that left bottom window, sets[0].elements gets changed, what's happening?
You are storing the address of a local variable on this line:
set.elemetns = elements;
That is undefined behaviour. Don't do it!
If you want to copy the string, do one of the following:
Change the structure to store a char array and use strncpy to copy the string; or
Duplicate the string (and remember to free it later): set.elemetns = strdup(elements);
In a completely separate issue, you have implemented a function getString that seems to do roughly what fgets does. You should use fgets instead.

Resources