C Program hangs after trying to call function from main - c

This is the code:
#include <stdlib.h>
#include <stdio.h>
#include "descartes.h"
/*
* Eulidean travelling salesman
*/
#define MAXCITIES 100
#define FALSE 0
#define TRUE 1
point_t city [MAXCITIES];
int numCities = 0;
int ReadCities(void);
double TourLength(lineSeg_t cityLines[]);
void DrawTour(void);
int main(void) {
printf ("main1\n");
OpenGraphics();
printf ("main2\n");
ReadCities();
DrawTour();
double TourLength(lineSeg_t cityLines[]);
CloseGraphics();
return EXIT_SUCCESS;
}
int ReadCities(void) {
printf ("ReadCities1");
int i = 1;
printf ("ReadCities2");
city[0] = GetPoint();
while ((XCoord(city[i])) >= 0) {
city[i] = GetPoint();
printf ("(%d, %d)", XCoord(city[i]), YCoord(city[i]));
numCities++;
i++;
}
if (numCities <= MAXCITIES) {
return TRUE;
}
else {
return FALSE;
}
}
double TourLength(lineSeg_t cityLines[]) {
double totLen = 0;
int i;
for (i = 0; i < (numCities - 1); i++) {
totLen += Length(cityLines[i]);
}
return totLen;
}
void DrawTour(void) {
lineSeg_t cityLines[MAXCITIES];
int i;
for (i = 0; i < (numCities - 1); i++) {
cityLines[i] = LineSeg(city[i], city[i + 1]);
DrawLineSeg(cityLines[i]);
}
}
When I run the program it prints:
main1
main2
Then the program hangs. I would at least expect it to call ReadCities() and at get as far as printing
ReadCities1
ReadCities2
but no matter what I try it just hangs with a flashing cursor in the terminal after printing main2. There might also be other mistakes in the code but I can't even get far enough to test it out!
Sorry if it's something obvious, i'm new to programming!
Cheers!

Not really sure what this line:
while ((XCoord(city[i])) >= 0)
Is returning, seems this loop might not be breaking. In a situation like this I'd printf() the value ofo XCoord(city[i]) within my loop to see what value is actually in there...
Using printf()'s can be quite useful for things like this.
Also, as someone said there's a function prototype declaration in main:
double TourLength(lineSeg_t cityLines[]);

Related

Recursive print of binary number

I'm struggling to write a recursive way to print a binary number. Here is what I have so far:
int bin(unsigned char n)
{
if (n==0) {
return 0;
} else {
printf("%d", bin(n<<1));
}
}
bin(7)
What seems to be wrong with the logic above?
A few errors such as using << (shift up) instead of >> (shift down). Also not always returning something. I'm surprised the compiler didn't pull you up on that. You don't gain anything from a return value, So you may as well get rid of it.
A simple implementation could look like this. We need to have the wrapped function (bin_recur) to allow us to differentiate between 0 the input value and 0 which signifies its time to stop recursion.
#include <stdio.h>
void bin_recur(unsigned char n)
{
if (n > 0)
{
printf("%d", n & 1);
bin_recur(n >> 1);
}
}
void bin(unsigned char n)
{
if (n == 0)
{
printf("0\n");
} else
{
bin_recur(n);
printf("\n");
}
}
int main()
{
for(unsigned i = 0; i < 10; i++)
{
bin(i);
}
}
The fact that your bin function calls printf is not completely ideal. This is what's known as tight coupling and the function could be more reusable if it was not bound to how it is presented. Perhaps copying to a string is a good way or even using fprintf to print to a file.
Stopping when n is 0 is wrong.
This fails for the trivial case where n is 0 to start with.
What you really need to do is pass down a shift amount as a second argument and stop after 8 bits.
Using the return with value just gets in the way.
Here's some refactored code with a full diagnostic test:
#include <stdio.h>
void
bin2(unsigned char n,int shf)
{
if (shf <= 7) {
bin2(n,shf + 1);
printf("%d", (n >> shf) & 1);
}
}
void
bin(unsigned char n)
{
bin2(n,0);
}
int
main(void)
{
for (unsigned int chr = 0; chr <= 0xFF; ++chr) {
printf("%2.2X: ", chr);
bin((unsigned char) chr);
printf("\n");
}
return 0;
}
please add this lines to your code.
void binary(int n) {
if(n==0)
return;
binary(n/2);
printf("%d",n%2);
}
You need the print call to execute after the recursive function for this to work. Here's an example:
void bin(unsigned char n)
{
if (n > 1) bin(n>>1);
putchar(n&1 ? '1' : '0');
}
int main(void)
{
for (unsigned char i = 255; i; i--) {
printf("%d --> ", i), bin(i);
getchar(); // inspect element if you want
}
}
Link to running code here.

Check for palindrome using stack in C

I'm new to C, and I've been given a question to write a program to check palindrome words.
I did the following code, it gives an output. but the output is always "No". The idea of what I did in this code is, I first divided the string and pushed them into one stack (stacka). then pushed the rest of the letters to another stack(stackb). Then I pop both of those stacks and check whether the letter returning from each pop function(of stacka and stackb) is equal or not. if not it will return 0.
below is the code.
Thank you in advance. Have a nice day!.
#include <stdio.h>
#include <string.h>
char stacka[5];
char stackb[5];
int topa = -1;
int topb = -1;
void pusha(char e) {
topa++;
stacka[topa] = e;
}
void pushb(char e) {
topb++;
stackb[topb] = e;
}
char popa() {
char e = stacka[topa];
topa--;
return e;
}
char popb() {
char e = stackb[topb];
topb--;
return e;
}
int palindrome(char str[]) {
int i, length = strlen(str);
int mid = length / 2;
for (i = 0; i < mid; i++) {
pusha(str[i]);
}
if (length % 2 != 0) {
i++;
}
for (i = length - 1; i >= mid; i--) {
pushb(str[i]);
}
int f;
for (f = mid; f >= 0; f--) {
char ele1 = popa();
char ele2 = popb();
if (ele1 != ele2)
return 0;
}
return 1;
}
int main() {
char str[] = "madam";
if (palindrome(str)) {
printf("Yes");
} else
printf("No");
}
At a first glance, I have found the following issues in your code.
if(length % 2 !=0)
{
i++;
}
for(i=length-1;i>=mid;i--)
{
pushb(str[i]);
}
Your if block does not make any impact on the code and it is unnecessary as well. for loop has an issue as well which can cause your problem.
Let me elaborate a bit. Let's say your input is "madam" and according to your solution, first for loop is doing ok.
int mid=length/2;
for(i=0;i<mid;i++)
{
pusha(str[i]);
}
As your input is "madam" your value for mid would be 2. so, the first stack will contain the letter, 'm', 'a'. This is alright up to this.
In the second for loop there is a issue,
for(i=length-1;i>=mid;i--)
{
pushb(str[i]);
}
According to this stack will contain 'm', 'a', 'd'.
Now I would say the correction here according to me. First of all, you remove the first if block, then do this modification on the second for loop.
for(i=length-1;i>mid;i--)
{
pushb(str[i]);
}
Then finally in last for loop,
for(f=mid-1;f>=0;f--)
{
char ele1=popa();
char ele2=popb();
if(ele1!=ele2)
return 0;
}
I have not compiled and run the code with my given corrections. But I think this will help you to figure out the issues with your code.
First u change the condition of for loop in palindrome function.
for(i=length-1;i>mid;i--)
{
pushb(str[i]);
}
தலைவா எனக்கு ஆங்கிலம் நல்லா வராது.
First u change the condition of for loop in palindrome function.
for(i=length-1;i>mid;i--)
{
pushb(str[i]);
}
Your program is correct.

Understanding returning values functions C

I'm trying to understand how the return value of a function works, through the following program that has been given to me,
It goes like this :
Write a function that given an array of character v and its dim, return the capital letter that more often is followed by its next letter in the alphabetical order.
And the example goes like : if I have the string "B T M N M P S T M N" the function will return M (because two times is followed by N).
I thought the following thing to create the function:
I'm gonna consider the character inserted into the array like integer thank to the ASCII code so I'm gonna create an int function that returns an integer but I'm going to print like a char; that what I was hoping to do,
And I think I did, because with the string BTMNMPSTMN the function prints M, but for example with the string 'ABDPE' the function returns P; that's not what I wanted, because should return 'A'.
I think I'm misunderstanding something in my code or into the returning value of the functions.
Any help would be appreciated,
The code goes like this:
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int trovato;
for(int j=0;j<DIM-1;j++) {
if (a[j]- a[j+1]==-1) {
trovato=a[j];
}
}
return trovato;
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("%c",maxvolte(v,dim));
return 0;
}
P.S
I was unable to insert the value of the array using in a for scanf("%c,&v[i]) or getchar() because the program stops almost immediately due to the intepretation of '\n' a character, so I tried with strings, the result was achieved but I'd like to understand or at least have an example on how to store an array of character properly.
Any help or tip would be appreciated.
There are a few things, I think you did not get it right.
First you need to consider that there are multiple pairs of characters satisfying a[j] - a[j+1] == -1
.
Second you assume any input will generate a valid answer. That could be no such pair at all, for example, ACE as input.
Here is my fix based on your code and it does not address the second issue but you can take it as a starting point.
#include <stdio.h>
#include <assert.h>
int maxvolte(char a[],int DIM) {
int count[26] = {0};
for(int j=0;j<DIM-1;j++) {
if (a[j] - a[j+1]==-1) {
int index = a[j] - 'A'; // assume all input are valid, namely only A..Z letters are allowed
++count[index];
}
}
int max = -1;
int index = -1;
for (int i = 0; i < 26; ++i) {
if (count[i] > max) {
max = count[i];
index = i;
}
}
assert (max != -1);
return index + 'A';
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("answer is %c\n",maxvolte(v,dim));
return 0;
}
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int hold;
int freq;
int max =0 ;
int result;
int i,j;
for(int j=0; j<DIM; j++) {
hold = a[j];
freq = 0;
if(a[j]-a[j+1] == -1) {
freq++;
}
for(i=j+1; i<DIM-1; i++) { //search another couple
if(hold==a[i]) {
if(a[i]-a[i+1] == -1) {
freq++;
}
}
}
if(freq>max) {
result = hold;
max=freq;
}
}
return result;
}
int main()
{
char v[] = "ABDPE";
int dim = sizeof(v) / sizeof(v[0]);
printf("\nresult : %c", maxvolte(v,dim));
return 0;
}

Function is being called four times per loop when there are only two calls to it

I'm very new to programming in C, and have pretty rusty programming skills overall. In order to learn C and re-orient myself with programming in general, I'm challenging myself to try and make a simple rougelike using ncurses.
I've set up a "log", which I should be able to push messages to - the most recent 10 message should be displayed. In order to test this, I've made it so each time either the player or the very simple randomly-moving mob takes a step, a log message is pushed saying "step [direction]". However, even though they each only take one step, for some reason, four messages are pushed to the log. The second-to-most-recent one is always the actual direction the character moved, and I presume one of the other two is the mob moving, but I don't know the origin of the other two. Does anyone spot anything glaring in my code that might be causing this issue? All help is appreciated, thanks!
(I believe the only major relevant sections to look at should be the main() function, pushToLog(), printLog(), and moveCreature(). That said, there is a chance the problem might be somewhere else. I'm not sure.)
#include <stdlib.h>
#include <stdio.h>
#include <ncurses.h>
#include <unistd.h>
#include <string.h>
#define up 65
#define down 66
#define right 67
#define left 68
#define quit 113
struct creature {
int x;
int y;
int hp;
int maxhp;
};
void setupMap();
struct creature setupCreature();
void moveCreature();
void pushToLog();
void printLog();
int breakFlag = FALSE;
char mapShape[15][15];
char mapFeatures[15][15];
char outputLog[10][60];
int main(int argc, char *argv[]){
struct creature player = setupCreature(4, 4, 100, 100);
struct creature mob = setupCreature(5, 7, 100, 100);
setupMap();
initscr();
noecho();
curs_set(FALSE);
while(1){
for (int i = 0; i < 15; i++){
for (int c = 0; c < 15; c++){
mvprintw(c, i, "%c", mapShape[i][c]);
}
}
mvprintw(player.y, player.x, "%c", '#');
mvprintw(mob.y, mob.x, "%c", 'd');
printLog();
int input = getch();
moveCreature(input, &player);
int mobDir = rand() % (68 + 1 - 65) + 65;
moveCreature(mobDir, &mob);
refresh();
usleep(300);
if (breakFlag == TRUE){
break;
}
}
endwin();
return 0;
}
void moveCreature(int dir, struct creature *subject){
int next;
if (dir == up){
next = (subject->y - 1);
if (mapShape[subject->x][next] != '#'){
subject->y = next;
pushToLog("step up ");
}
}
else if (dir == down){
next = (subject->y + 1);
if (mapShape[subject->x][next] != '#'){
subject->y = next;
pushToLog("step down ");
}
}
else if (dir == right){
next = (subject->x + 1);
if (mapShape[next][subject->y] != '#'){
subject->x = next;
pushToLog("step right ");
}
}
else if (dir == left){
next = (subject->x - 1);
if (mapShape[next][subject->y] != '#'){
subject->x = next;
pushToLog("step left ");
}
}
else if (dir == quit){
breakFlag = TRUE;
}
}
void pushToLog(char string[]){
for (int i = 10; i > 0; i--){
strcpy(outputLog[i], outputLog[i-1]);
}
strcpy(outputLog[0], string);
}
void printLog(){
for (int i = 0; i < 10; i++){
mvprintw(28-i, 0, outputLog[i]);
}
}
struct creature setupCreature(int x,int y,int hp,int maxhp){
struct creature frankenstien;
frankenstien.x = x;
frankenstien.y = y;
frankenstien.hp = hp;
frankenstien.maxhp = maxhp;
return frankenstien;
}
void setupMap(){
for (int i = 0; i < 15; i++){
for (int c = 0; c < 15; c++){
mapShape[i][c] = '.';
}
}
for (int i = 0; i < 15; i++){
mapShape[0][i] = '#';
mapShape[14][i] = '#';
mapShape[i][0] = '#';
mapShape[i][14] = '#';
}
}
Your problem is at the input stage. You expect directional commands via the arrow keys, but those generate multiple bytes per keypress. All but one are invalid as commands.
As a secondary problem, you do not reject invalid commands. You go ahead and move the mob after each command character read, whether that command was valid or not.
The overall upshot is that when you press an arrow key, the program zips through three iterations of the main loop, one right after the other, producing log messages for one valid player move, no log messages for two invalid player moves, and log messages for each of three mob moves.
You could have detected this by logging invalid commands, or by running your program in a debugger.

Very Simple C Program Crashing

I'm having a simple issue where my C executable is crashing after attempting to grab input from the user.
The idea of the program is to populate an array and eventually generate some data on that array. So far I have attempted to grab input from the user and immediately after the exe crashes. I've also edited the code temporarily whilst trying to debug what the issue is with no success. I have not touched c in a number of years and was very young when I had last and am quite a novice.
Can someone advise on any possible solution to why it would be crashing?
#include <stdio.h>
#include <stdbool.h>
double get_double(char prompt[50])
{
double tempDouble = 0;
printf("%s", prompt);
scanf("%d", tempDouble);
return tempDouble;
}
void populate_array(double *pData[])
{
int i = 0;
*pData[0] = get_double("Please Enter A Number : ");
//for(i = 0; i < sizeof(*pData); i++)
//{
//*pData[i] = get_double("Please Enter A Number : ");
//}
}
double get_sum(double data[10])
{
int i = 0;
double result = 0;
for (i = 0; i < sizeof(data); i++)
{
result += data[i];
}
return result;
}
int main()
{
//Variable Declarations
bool running = true;
bool playAgain = false;
double numbers[10];
double sum, min, max, var, dev;
//Process
populate_array(&numbers);
sum = get_sum(numbers);
printf("%d",sum);
}
void populate_array(double *pData[]) accepts an array of pointer, while you pass it just an array, it should be:
void populate_array(double pData[])
{
int i = 0;
pData[0] = get_double("Please Enter A Number : ");
}
Also, when you read the double, it should be:
// as proposed by Jonathan, the format string should contain '%lf' for double, I overlooked it.
scanf("%lf", &tempDouble);
if you pass scanf just tempDouble, it treats its value as an address, which is invalid address of course.
Your code contains:
scanf("%d", tempDouble);
You need to add & to the parameter you use in scanf().
And %d is used with integer. When you want to use double you need to use %lf; with a float, you'd use %f.
for (i = 0; i < sizeof(data); i++)
this will iterate after you reached the boundaries of the array.
for (i = 0; i < sizeof(data)/sizeof(double); i++)
this may be works but is not elegant
double get_sum(int numberOfElements, double data[10])
{
int i = 0;
double result = 0;
for (i = 0; i < numberOfElements; i++)
{
result += data[i];
}
return result;
}
this is the better approach
sum = get_sum(10, numbers);
In the main function call the get_sum function like this

Resources