shea shea - 3 months ago 6
C Question

C: Function Running differently in Separate instances

I am following the iTunes University: Harvard CS50 lectures in order to learn the basics of programming. I am currently trying to create a program for a text cypher. Here is the code for the entire program.

#include<stdio.h>
#include<cs50.h>
#include<stdlib.h>
#include<string.h>

int cyphmain (void);
int decyphmain (void);
int maincalc (int k);
int dmaincalc (int k);
int uppercalc (int u, int k);
int lowercalc (int u, int k);
int duppercalc (int u, int k);
int dlowercalc (int u, int k);

int
main(void) //Main Function begins by asking the user if he would like to Cypher or Decypher his text
{
char h;
printf("Do You Want Cypher(c) or Decypher(d)?:");
scanf("%c",&h);
if (h==99) //Checks ascii of "c"(99) and runs the cypher main function
cyphmain();
else if (h==100) //Checks ascii of "d"(100) and runs the decypher main function
decyphmain();
else
return 0;
}

int cyphmain (void) //Cypher Main Function
{
int k;
printf("What is the Cypher Number:"); //Gets the rot number
scanf("%d",&k);
if (k>25) //Ensures that the User only choses a number from 1-25
{ while (k>25) //Continues to ask user for a number until they input a value <=25
{
printf("Sorry Please Choose A Number from 1-25 only:");
int l=GetInt();
k=l;
}
maincalc(k); //as soon as a valid input is received maincalc function is run
}
else //in this case a valid input has been recieved and maincalc runs
maincalc(k);
return 0;
}

int decyphmain (void) //Decypher Main Function
{
int k;
printf("What is the Cypher Number:"); //Gets the rot number
scanf("%d",&k);
if (k>25) //Ensures that the User only choses a number from 1-25
{ while (k>25) //Continues to ask user for a number until they input a value <=25
{
printf("Sorry Please Choose A Number from 1-25 only:");
int l=GetInt();
k=l;
}
dmaincalc(k); //as soon as a valid input is received maincalc funtion is run
}
else //in this case a valid input has been recieved and maincalc runs
dmaincalc(k);
return 0;
}

int maincalc(int k) //The Calculation Function for Cyphering
{
char *s;
printf("Please enter the phrase that you would like to code:");
scanf("%s",&s);
int i=0;
int n=strlen(s);

while(i<n)
{
if(s[i]>=65&&s[i]<=90) //For Uppercase letters
{
int u=s[i];
int c=uppercalc(u,k); //Hands off the character to a function to cypher Upper Case Letters
printf("%c",c);
}
else if(s[i]>=97&&s[i]<=122) //For Lowercase letters
{
int u=s[i];
int c=lowercalc(u,k); //Hands off the character to a function to cypher Lower Case Letters
printf("%c",c);
}
else
printf("%c",s[i]); //For non letters
i++;
}
printf("\n");
return 0;
}


int uppercalc(int u, int k) //Algorithm used to cypher Upper Case letters
{
if(u+k<=90)
{
int c=u+k;
return (c);
}
else
{
if (((u+k)/26)==3)
{
int c=((u+k)%26)+52;
return (c);
}
else
{
int c=((u+k)%26)+78;
return (c);
}
}
}

int lowercalc(int u, int k) //Algorithms used to Cypher lower case letters
{
if(u+k<=122)
{
int c=u+k;
return (c);
}
else
{
if (((u+k)/26)==4)
{
int c=((u+k)%26)+78;
return (c);
}
else
{
int c=((u+k)%26)+104;
return (c);
}
}
}

int dmaincalc(int k) //The Calculation Function for Decyphering
{
char *s;
printf("Please enter the phrase that you would like to decode:");
scanf("%s",&s);
int i=0;
int n=strlen(s);

while(i<n)
{
if(s[i]>=65&&s[i]<=90) //For Uppercase letters
{
int u=s[i];
int c=duppercalc(u,k);
printf("%c",c);
}
else if(s[i]>=97&&s[i]<=122) //For Lowercase letters
{
int u=s[i];
int c=dlowercalc(u,k);
printf("%c",c);
}
else
printf("%c",s[i]); //For non letters
i++;
}
printf("\n");
return 0;
}

int duppercalc(int u, int k) //Algorithm to decypher Upper Case letters
{
if(u-k>=65)
{
int c=u-k;
return (c);
}
else
{
if (((u-k)/26)==2)
{
int c=((u-k)%26)+78;
return (c);
}
else
{
int c=((u-k)%26)+52;
return (c);
}
}
}

int dlowercalc(int u, int k) //Algorithms to decypher lower case letters
{
if(u-k>=97)
{
int c=u-k;
return (c);
}
else
{
if (((u-k)/26)==3)
{
int c=((u-k)%26)+104;
return (c);
}
else
{
int c=((u-k)%26)+78;
return (c);
}
}
}


The Program begins by asking the user whether he wants to Cypher or Decypher by inserting either char "c" or "d" and runs either the cyphmain (if cyphering) or dcecyphmain (if decphering) functions. This works fine

The program then asks the user for the rot number and then asks the user to input a phrase. This also works fine.

However, after entering the words to (de)cypher the program crashes with a segmentation fault, which leads me to believe that the error lies in the maincalc/dmaincalc functions. (Note that there are essentially two copies of each function one for cyphering and another for decyphering, they are exactly the same except for a few changes in the text and the actual math involved in cyphering or decyphering the text).

Here's an example of the fault

Do You Want Cypher(c) or Decypher(d)?:d
What is the Cypher Number:2
Please enter the phrase that you would like to decode: Hello
Segmentation fault (core dumped)

Answer

Your error is here:

char *s;
printf("Please enter the phrase that you would like to code:");  
scanf("%s",&s);

This does not allocate space for a string. You can either use malloc to allocate space, or put the string on the stack.

char *s = malloc(sizeof(char) * 50); /* option 1*/
char s[50]; /* option 2 */

For option 1, note that sizeof(char) is always 1, I just put that there for completeness. Also don't forget that you have to call free(s) when you're done with the string.