Post Order print without recursion - c
This is what i have so far. I really don't understand where i went wrong. It needs to print after it has visited the left most node and then right then print.
void printPostOrderIterative(BSTNode *root)
{
BSTNode *cur;
Stack s;
s.top = NULL;
Stack output;
output.top = NULL;
if (!root) {
return;
}
push(&s, root);
while (isEmpty(&s) != 1 ) {
cur = s.top;
push(&output,cur);
pop(&s);
if (cur->left){
push(&s, cur->left);
}
if (cur->right){
push(&s, cur->right);
}
}
while (isEmpty(&output) != 1) {
printf("%d", output.top);
pop(&output);
}
}
Currently, the code just keeps looping in the first while loop.
Here is some working code. I had to implement an approximation to your stack code, and the BST code, but I made only very simple changes to your function. There are arguments that I should not have had to do the creation: Stack Overflow encourages you to create an MCVE (How to create a Minimal, Complete, and Verifiable Example?)
SSCCE (Short, Self-Contained, Correct Example) — two names and links for the same basic idea.
Without any major algorithmic tweaks, your code (a) completes and (b) produces the same answer as a recursive post-order print function (on one sample data set).
static void printPostOrderIterative(BSTNode *root)
{
if (!root) // Moved to avoid stack initialization before returning
return; // …ditto…
Stack s;
Stack output;
init(&s); // Different initialization
init(&output); // Different initialization
push(&s, root);
while (isEmpty(&s) != 1)
{
BSTNode *cur = top(&s); // Different code
push(&output, cur);
pop(&s);
if (cur->left)
push(&s, cur->left);
if (cur->right)
push(&s, cur->right);
}
while (isEmpty(&output) != 1)
{
BSTNode *c = top(&output); // Different code
printf(" %d", c->data); // Added space
pop(&output);
}
putchar('\n'); // Extra code
clean(&s); // Extra code
clean(&output); // Extra code
}
Thus the problem is probably not in the code you show — it is more likely in the code you don't show. My best guess is that the stack implementation is slightly faulty, but since you don't show it, it is hard to be sure.
Full code
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct BSTNode BSTNode;
struct BSTNode
{
int data;
BSTNode *left;
BSTNode *right;
};
typedef struct Stack
{
size_t size;
size_t top;
BSTNode **stack;
} Stack;
static void err_syserr(const char *fmt, ...)
{
int errnum = errno;
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
if (errnum != 0)
fprintf(stderr, "(%d: %s)\n", errnum, strerror(errnum));
exit(1);
}
static void push(Stack *sp, BSTNode *np)
{
assert(sp != 0 && np != 0);
if (sp->top == sp->size)
{
size_t n_size = (sp->size + 2) * 2;
void *n_data = realloc(sp->stack, n_size * sizeof(*sp->stack));
if (n_data == 0)
err_syserr("Out of memory (%zu bytes requested)\n",
n_size * sizeof(*sp->stack));
sp->stack = n_data;
sp->size = n_size;
}
sp->stack[sp->top++] = np;
}
static bool isEmpty(Stack *sp)
{
return sp->top == 0;
}
static void pop(Stack *sp)
{
if (!isEmpty(sp))
sp->top--;
}
static void init(Stack *sp)
{
sp->top = 0;
sp->size = 0;
sp->stack = 0;
}
static BSTNode *top(Stack *sp)
{
if (sp->top == 0)
return 0;
return sp->stack[sp->top - 1];
}
static void clean(Stack *sp)
{
while (sp->top > 0)
free(sp->stack[--sp->top]);
free(sp->stack);
init(sp);
}
static BSTNode *new_node(int data)
{
BSTNode *np = malloc(sizeof(*np));
if (np == 0)
err_syserr("Out of memory (%zu bytes requested)\n", sizeof(*np));
np->data = data;
np->left = 0;
np->right = 0;
return np;
}
static void printPostOrderIterative(BSTNode *root)
{
if (!root)
return;
Stack s;
Stack output;
init(&s); // Different initialization
init(&output); // Different initialization
push(&s, root);
while (isEmpty(&s) != 1)
{
BSTNode *cur = top(&s); // Different code
push(&output, cur);
pop(&s);
if (cur->left)
push(&s, cur->left);
if (cur->right)
push(&s, cur->right);
}
while (isEmpty(&output) != 1)
{
BSTNode *c = top(&output);
printf(" %d", c->data);
pop(&output);
}
putchar('\n'); // Extra code
clean(&s); // Extra code
clean(&output); // Extra code
}
static void printPostOrderRecursive(BSTNode *root)
{
if (root != 0)
{
printPostOrderRecursive(root->left);
printPostOrderRecursive(root->right);
printf(" %d", root->data);
}
}
static void printInOrderRecursive(BSTNode *root)
{
if (root != 0)
{
printInOrderRecursive(root->left);
printf(" %d", root->data);
printInOrderRecursive(root->right);
}
}
static BSTNode *bst_add(BSTNode *root, int data)
{
if (root == 0)
root = new_node(data);
else if (root->data > data)
root->left = bst_add(root->left, data);
else
root->right = bst_add(root->right, data);
return root;
}
static void bst_destroy(BSTNode *root)
{
if (root != 0)
{
bst_destroy(root->left);
bst_destroy(root->right);
free(root);
}
}
int main(void)
{
int data[] =
{
71, 57, 4, 31, 47, 65, 69, 65, 98, 81,
54, 58, 17, 37, 48, 64, 64, 93, 40, 22,
45, 62, 99, 47, 18, 86, 67, 99, 68, 27,
};
enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
BSTNode *root = 0;
for (int i = 0; i < NUM_DATA; i++)
{
root = bst_add(root, data[i]);
printInOrderRecursive(root);
putchar('\n');
}
printPostOrderRecursive(root);
putchar('\n');
printPostOrderIterative(root);
bst_destroy(root);
return 0;
}
Sample output
71
57 71
4 57 71
4 31 57 71
4 31 47 57 71
4 31 47 57 65 71
4 31 47 57 65 69 71
4 31 47 57 65 65 69 71
4 31 47 57 65 65 69 71 98
4 31 47 57 65 65 69 71 81 98
4 31 47 54 57 65 65 69 71 81 98
4 31 47 54 57 58 65 65 69 71 81 98
4 17 31 47 54 57 58 65 65 69 71 81 98
4 17 31 37 47 54 57 58 65 65 69 71 81 98
4 17 31 37 47 48 54 57 58 65 65 69 71 81 98
4 17 31 37 47 48 54 57 58 64 65 65 69 71 81 98
4 17 31 37 47 48 54 57 58 64 64 65 65 69 71 81 98
4 17 31 37 47 48 54 57 58 64 64 65 65 69 71 81 93 98
4 17 31 37 40 47 48 54 57 58 64 64 65 65 69 71 81 93 98
4 17 22 31 37 40 47 48 54 57 58 64 64 65 65 69 71 81 93 98
4 17 22 31 37 40 45 47 48 54 57 58 64 64 65 65 69 71 81 93 98
4 17 22 31 37 40 45 47 48 54 57 58 62 64 64 65 65 69 71 81 93 98
4 17 22 31 37 40 45 47 48 54 57 58 62 64 64 65 65 69 71 81 93 98 99
4 17 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 69 71 81 93 98 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 69 71 81 93 98 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 69 71 81 86 93 98 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 67 69 71 81 86 93 98 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 67 69 71 81 86 93 98 99 99
4 17 18 22 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 67 68 69 71 81 86 93 98 99 99
4 17 18 22 27 31 37 40 45 47 47 48 54 57 58 62 64 64 65 65 67 68 69 71 81 86 93 98 99 99
18 27 22 17 45 40 37 47 48 54 47 31 4 62 64 64 58 68 67 65 69 65 57 86 93 81 99 99 98 71
18 27 22 17 45 40 37 47 48 54 47 31 4 62 64 64 58 68 67 65 69 65 57 86 93 81 99 99 98 71
Discussion
Since you used interleaved declarations and statement, you're using at least C99 so I've used <stdbool.h> and bool type. This code compiles cleanly, at least when compiled with the options (Mac OS X 10.11.4, GCC 5.3.0):
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
> -Wold-style-definition -Werror nr-post.c -o nr-post
$
The code runs cleanly under valgrind (3.12.0-SVN).
The first lines of output are printed in-order as the tree is built up (from 30 integers from the range 0..99 generated at random). This allows me to see that the tree is built correctly from the ground up. The last two lines of output are first from printPostOrderRecursive(), a simple recursive implementation of post-order printing, and then from (my mild adaptation of your) printPostOrderIterative().
Without your stack implementation available, I have to guess that you have a problem somewhere in there. With a straight-forward implementation of a stack as shown (where the top is an index into the array of node pointers), your code is fine. We can't tell whether you have compilation warnings you're ignoring.
Hmmm, reviewing my code, I see it doesn't check that top() returns a non-null pointer. It's tempting to add an assertion, and a run-time error rather than returning null. There are plenty of other assertions that could be added — non-null stack pointers passed to the stack functions, in particular.
Related
C return big number confusion
When I input the string instead of y or n in this code, it will return the large number. So I want to know how to fix it. My first thought is that if I input the string instead of this, it will return to the first paragraph and run again. But when I trying to use this, it will return and run again. But It will save the string and change it into an ASCII code. #include <stdlib.h>; #include <stdio.h>; int main() { int num = 1; //設置迴圈變數 int change; //設置可變動變數 int count=0; // 跑了幾次 char ans1,ans2,ans3,ans4,ans5,ans6,ans7 ; //答案共7個 int final_ans = 0;//最後答案 printf("thinking a number on your mind, and I will guess it!\n\n"); first: for(num=1; num<=100; num+=2) { ++count; printf("%-4.2d", num);//4格寬 數字顯示2位 if(count%9==0) { printf("\n");//每執行9次換行 } } count = 0;//清空變數 printf("\n"); printf("Is your number on the table (y/n)? \n"); scanf("%s", &ans1); if((ans1=='Y') || (ans1=='y')) { //若有數字 final_ans += 1; } second: for(num=2; num<=100; num+=2) { change = num; ++count; if(count%2==0) { change--; } printf("%-4.2d", change);//4格寬 數字顯示2位 if(count%9==0) { printf("\n");//每執行9次換行 } } printf("\n"); printf("Is your number on the table (y/n)? \n"); scanf("%s", &ans2); count = 0;//清空變數 change = 0;//清空變數 if((ans2=='Y') || (ans2=='y')) { final_ans += 2; } third: for(num=4; num<=100; num++) { change = num; ++count; if(count%4==1&&num!=4) { num+=4; } printf("%-4.2d", num);//4格寬 數字顯示2位 if(count%9==0) { printf("\n");//每執行9次換行 } } printf("\n"); printf("Is your number on the table (y/n)? \n"); scanf("%s", &ans3); count = 0;//清空變數 change = 0;//清空變數 if((ans3=='Y') || (ans3=='y')) { final_ans +=4; } fourth: for(num=8; num<=100; num++) { change = num; ++count; if(count%8==1&&num!=8) { num+=8; } if(num>100) { break; } printf("%-4.2d", num);//4格寬 數字顯示2位 if(count%9==0) { printf("\n");//每執行9次換行 } } printf("\n"); printf("Is your number on the table (y/n)? \n"); scanf("%s", &ans4); count = 0;//清空變數 change = 0;//清空變數 if((ans4=='Y') || (ans4=='y')) { final_ans += 8; } fifth: for(num=16; num<=100; num++) { change = num; ++count; if(count%16==1&&num!=16) { num+=16; } if(num>100) { break; } printf("%-4.2d", num);//4格寬 數字顯示2位 if(count%9==0) { printf("\n");//每執行9次換行 } } printf("\n"); printf("Is your number on the table (y/n)? \n"); scanf("%s", &ans5); count = 0;//清空變數 change = 0;//清空變數 if((ans5=='Y') || (ans5=='y')) { final_ans += 16; } sixth: for(num=32; num<=100; num++) { change = num; ++count; if(count%32==1&&num!=32) { num+=32; } if(num>100) { break; } printf("%-4.2d", num);//4格寬 數字顯示2位 if(count%9==0) { printf("\n");//每執行9次換行 } } printf("\n"); printf("Is your number on the table (y/n)? \n"); scanf("%s", &ans6); count = 0;//清空變數 change = 0;//清空變數 if((ans6=='Y') || (ans6=='y')) { final_ans += 32; } seventh: for(num=64; num<=100; num++) { ++count; printf("%-4.2d", num);//4格寬 數字顯示2位 if(count%9==0) { printf("\n");//每執行9次換行 } } printf("\n"); printf("Is your number on the table (y/n)? \n"); scanf("%s", &ans7); if((ans7=='Y') || (ans7=='y')) { final_ans += 64; } else if((ans1=='n') || (ans1=='N')) { //若無數字 final_ans += 0; goto second;//回到第二個table } else if((ans2=='n') || (ans2=='N')) { //若無數字 final_ans += 0; goto third;//回到第三個table } else if((ans3=='n') || (ans3=='N')) { //若無數字 final_ans += 0; goto fourth;//回到第四個table } else if((ans4=='n') || (ans4=='N')) { //若無數字 final_ans += 0; goto fifth;//回到第五個table } else if((ans5=='n') || (ans5=='N')) { //若無數字 final_ans += 0; goto sixth;//回到第六個table } else if((ans6=='n') || (ans6=='N')) { //若無數字 final_ans += 0; goto seventh;//回到第七個table } else if((ans7=='n') || (ans7=='N')) { //若無數字 final_ans += 0; } if(final_ans<=100) { //判斷最後答案 printf("your secret number is %d",final_ans); } else if(final_ans>100) { printf("WRONG!%d is not a number form 1~100",final_ans); } }
you have put ; after every library please remove that #include <stdlib.h>; // remove the ; #include <stdio.h>; // remove the ; correct code must be #include <stdlib.h> #include <stdio.h> By editing that I got correct answers. it works for me. I have think about 73 output -: thinking a number on your mind, and I will guess it! 01 03 05 07 09 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 Is your number on the table (y/n)? y 02 03 06 07 10 11 14 15 18 19 22 23 26 27 30 31 34 35 38 39 42 43 46 47 50 51 54 55 58 59 62 63 66 67 70 71 74 75 78 79 82 83 86 87 90 91 94 95 98 99 Is your number on the table (y/n)? n 04 05 06 07 12 13 14 15 20 21 22 23 28 29 30 31 36 37 38 39 44 45 46 47 52 53 54 55 60 61 62 63 68 69 70 71 76 77 78 79 84 85 86 87 92 93 94 95 100 Is your number on the table (y/n)? n 08 09 10 11 12 13 14 15 24 25 26 27 28 29 30 31 40 41 42 43 44 45 46 47 56 57 58 59 60 61 62 63 72 73 74 75 76 77 78 79 88 89 90 91 92 93 94 95 Is your number on the table (y/n)? y 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 Is your number on the table (y/n)? n 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 96 97 98 99 100 Is your number on the table (y/n)? n 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 Is your number on the table (y/n)? n 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 Is your number on the table (y/n)? y your secret number is 73
Issue with fscanf reading input file
I am trying to convert an input file from .txt to .csv. I've performed multiple tests using gdb and switched my code around. The code looks like it should work but for some reason it doesn't. I've tried using "while (fscanf(…arguments…) != EOF)" but I always end up in a never-ending loop when I know that the input file does end. Is it the way I'm trying to read the file that's the problem or something else? I'd greatly appreciate any advice. A sample of the input file (it's way too big. Also the potentiometer value is the only value that is consistently zero. All other values are greater than zero) time: 40 ms switch0: 1 switch1: 1 switch2: 1 switch3: 1 potentiometer: 0.00 temperature: 0.66 light: 0.23 --------------------------- time: 80 ms switch0: 1 switch1: 1 switch2: 1 switch3: 1 potentiometer: 0.00 temperature: 0.66 light: 0.23 --------------------------- time: 120 ms switch0: 1 switch1: 1 switch2: 1 switch3: 1 potentiometer: 0.00 temperature: 0.66 light: 0.23 --------------------------- The file that convert from txt to csv 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main() 5 { 6 FILE *data = fopen("data.csv","w"); 7 FILE *arduino = fopen("arduino.txt","r"); 8 9 if(arduino == NULL) 10 { 11 printf("error reading file\n"); 12 return 1; 13 } 14 if(data == NULL) 15 { 16 printf("error writing file\n"); 17 return 2; 18 } 19 20 fprintf(data,"Time,Switch0,Switch1,Switch2,Switch3,Potentiometer,Temperature,Light\n"); 21 22 int num1,num2,num3,num4,num5; 23 double num6,num7,num8; 24 25 double temp1[800]; 26 27 int count1 = 0; 28 29 while(count1<800) 30 { 31 fscanf(arduino,"%lf",&temp1[count1]); 32 count1++; 33 } 34 35 for(count1 = 0; count1 < 800; count1++) 36 { 37 printf("%lf",temp1[count1]); 38 } 39 40 41 int count2 = 0; 42 int i = 0; 43 44 while(count2 != 800) 45 { 46 for(i=0 ; i <8;i++) 47 { 48 if(i==7) 49 { 50 fprintf(data,"%lf\n",temp1[count2]); 51 } 52 53 else 54 { 55 fprintf(data, "%lf,", temp1[count2]); 56 } 57 count2++; 58 } 59 } 60 61 62 if (fclose(arduino)==EOF) 63 { 64 printf("error closing input file\n"); 65 } 66 if(fclose(data)==EOF) 67 { 68 printf("error closing output file\n"); 69 } 70 } and here's the output Time,Switch0,Switch1,Switch2,Switch3,Potentiometer,Temperature,Light 2 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 3 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 4 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 5 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 6 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 7 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 8 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 9 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 (still zeros across the board) 61 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 62 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 63 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 64 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 65 0.000000,0.000000,0.000000,0.000000,-nan,0.000000,0.000000,0.000000 66 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 67 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 68 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 69 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 70 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 71 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 72 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 73 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 74 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 75 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 76 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 77 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 78 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 79 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 80 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 81 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 82 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 83 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 84 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 85 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 86 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 87 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 88 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 89 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 90 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 91 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 92 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 93 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 94 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 95 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 96 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 97 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 98 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 99 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000 100 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,253700437344304240814662650531587413567701629019053044079803999006261210888228446189339915094527360 92923426425002851172634311446770729875573243622981632.000000,49038509684686202755808411764574575003743211375155249005916427827780247417991687082747214451 073341675744581253991867335918252416362555908299070786942125737694751726823604090062182039519355613866611467434357822207669472484839486934106348907556279 40839424.000000 101 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000
Checking the return value from fscanf() against the expected value, not against EOF is a good idea. #BLUEPIXY #Peter. This will identify/solve most of OP's problems. The data file has keywords in it, they needed to be scanned too. #user3386109 Suggest direct code to read the entire record with one fscanf(). struct kk { int time; int switchn[4]; double potentiometer, temperature, light; }; int data_kk_read(FILE *inf, struct kk *data) { int cnt = fscanf(inf, " time: %d ms switch0: %d switch1: %d switch2: %d" " switch3: %d potentiometer: %lf temperature: %lf light: %lf" " --------------------------- ", &data->time,&data->switchn[0],&data->switchn[1], &data->switchn[2], &data->switchn[3], &data->potentiometer, &data->temperature, &data->light); return cnt; } int data_kk_write(FILE *outf, unsigned n, const struct kk *data) { int cnt = fprintf(outf, "%3u %d, %d, %d, %d, %d, %.2lf, %.2lf, %.2lf\n", n, data->time, data->switchn[0], data->switchn[1], data->switchn[2], data->switchn[3], data->potentiometer, data->temperature, data->light); return cnt; } int main(void) { FILE *inf = fopen("data.txt", "r"); assert(inf); unsigned line = 0; struct kk data; int cnt; while ((cnt = data_kk_read(inf, &data)) == 8) { data_kk_write(stdout, ++line, &data); } fclose(inf); if (cnt != EOF) puts("Unexpected scanning problem"); return 0; } Output 1 40, 1, 1, 1, 1, 0.00, 0.66, 0.23 2 80, 1, 1, 1, 1, 0.00, 0.66, 0.23 3 120, 1, 1, 1, 1, 0.00, 0.66, 0.23
Equating with NULL in C
I was trying simple stack implementation in C. Here is my simple code: 1 #include "stdio.h" 2 #include "limits.h" 3 #include "malloc.h" 4 5 typedef struct StackEntry StackEntry; 6 7 struct StackEntry 8 { 9 int data; 10 StackEntry *next; 11 }; 12 13 StackEntry* createStack(){ 14 return NULL; 15 } 16 17 int isEmptyStack(StackEntry **pStackTop) 18 { 19 return *pStackTop == NULL; 20 } 21 22 void push(StackEntry **pStackTop, int pData) 23 { 24 StackEntry *lTempStackEntry; 25 lTempStackEntry = (StackEntry*)malloc(sizeof(StackEntry)); 26 27 if(!lTempStackEntry) 28 return; 29 30 lTempStackEntry->data = pData; 31 lTempStackEntry->next = *pStackTop; 32 33 *pStackTop = lTempStackEntry; 34 } 35 36 int pop(StackEntry **pStackTop) 37 { 38 int lTempData; 39 StackEntry *lTempStackEntry; 40 41 if(isEmptyStack(pStackTop)) 42 return INT_MIN; 43 44 lTempStackEntry = *pStackTop; 45 *pStackTop = (*pStackTop)->next; 46 lTempData = lTempStackEntry->data; 47 free(lTempStackEntry); 48 49 return lTempData; 50 } 51 52 int stackTop(StackEntry **pStackTop) 53 { 54 if(isEmptyStack(pStackTop)) 55 return INT_MIN; 56 57 return (*pStackTop)->data; 58 } 59 60 void deleteStack(StackEntry ** pStackTop) 61 { 62 StackEntry *secondTopNode, *topNode; 63 topNode = *pStackTop; 64 /* 65 * In this we free all the nodes from second top to bottom, 66 * by one by one attaching them to top->next. At the end 67 * we free the top node. 68 */ 69 while(topNode->next) 70 { 71 secondTopNode = topNode->next; 72 topNode->next = secondTopNode->next; //make third top node 73 //second top node 74 free(secondTopNode); 75 secondTopNode = NULL; 76 } 77 free(topNode); 78 topNode = NULL; 79 } 80 81 int main(void) { 82 // your code goes here 83 StackEntry *stack = createStack(); //stack: 0x0 84 printf("\n push 1"); 85 push(&stack,1); 86 printf("\n push 2"); 87 push(&stack,2); 88 printf("\n push 3"); 89 push(&stack,3); 90 printf("\n stack top: %d", stackTop(&stack)); 91 printf("\n pop: %d ",pop(&stack)); 92 printf("\n stack top: %d", stackTop(&stack)); 93 printf("\n pop: %d ",pop(&stack)); 94 printf("\n stack top: %d", stackTop(&stack)); 95 96 deleteStack(&stack); 97 printf("\n stack deleted."); 98 printf("\n is stack empty: %d", isEmptyStack(&stack)); //here it should print 1, but its printing 0 99 100 printf("\n push 1"); 101 push(&stack,1); 102 printf("\n push 2"); 103 push(&stack,2); 104 105 printf("\n pop: %d ",pop(&stack)); 106 printf("\n pop: %d ",pop(&stack)); 107 return 0; 108 } Output push 1 push 2 push 3 stack top: 3 pop: 3 stack top: 2 pop: 2 stack top: 1 stack deleted. is stack empty: 0 push 1 push 2 pop: 2 pop: 1 In deleteStack(), I free up all of the stack entry and set stack top to NULL. In isEmptyStack() check if the stack top is empty. So it should evaluate to 1 and line 98 should print 1 (i.e. true), but it prints 0. Whats wrong here? Here is the code on ideone. Debugging efforts I took:
In function deleteStack, you don't set stack to null instead a copy of stack pointer to null. What you do is: topNode = *pStackTop; topNode = NULL; Which is incorrect. What you should instead do is: *pStackTop = NULL;
Partial Threaded Sorting in C
I'm trying to do a partial sort with a threads, my current output it 27 12 21 48 15 28 82 69 35 91 13 82 33 35 46 5 35 28 87 95 0 10 20 22 23 30 52 80 86 96 3 8 42 53 67 70 70 71 75 79 5 8 8 18 41 43 70 79 86 88 10 51 56 60 65 84 87 91 94 99 23 25 38 39 40 44 51 56 69 75 20 21 25 29 29 38 66 71 73 96 33 50 9 6 13 27 97 21 70 22 3 4 6 6 7 15 34 59 63 70 As you can see I am getting it partially sorted I want my output to be this (no merging at the end) 12 15 21 27 28 35 48 69 82 91 5 13 28 33 35 35 46 82 87 95 0 10 20 22 23 30 52 80 86 96 3 8 42 53 67 70 70 71 75 79 5 8 8 18 41 43 70 79 86 88 10 51 56 60 65 84 87 91 94 99 23 25 38 39 40 44 51 56 69 75 20 21 25 29 29 38 66 71 73 96 6 9 13 21 22 27 33 50 70 97 3 4 6 6 7 15 34 59 63 70 I can get the right output if instead of using a struct I use &array[i] and manually input the length This is the code I have so far: #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <pthread.h> int cmpfunc(const void *a, const void *b) { return (*(int*)a - *(int*)b); } struct values { int *arrayptr; int length; }; void *thread_fn(void *a) { struct values *start = a; qsort(start->arrayptr, start->length, sizeof(int), cmpfunc); return (void*)a; } int main(int argc, const char *argv[]) { FILE *fp = fopen(argv[3], "r"); FILE *fp1 = fopen("numS1.dat", "w+"); //amount of threads int threadAmount = atoi(argv[1]); //size of input int numberAmount = atoi(argv[2]); //multidimensional array int array[threadAmount][numberAmount / threadAmount]; for (int i = 0; i < threadAmount; i++) for (int j = 0; j < numberAmount / threadAmount; j++) fscanf(fp, "%d", &array[i][j]); pthread_t threadid[threadAmount]; for (int i = 0; i < threadAmount; ++i) { struct values a = { array[i], numberAmount / threadAmount }; pthread_create(&threadid[i], NULL, thread_fn, &a); } for (int i = 0; i < threadAmount; ++i) pthread_join(threadid[i], NULL); for (int i = 0; i < threadAmount; i++) { if (i != 0) fprintf(fp1, "\n"); for (int j = 0; j < numberAmount / threadAmount; j++) fprintf(fp1 ,"%d ", array[i][j]); } return 0; } Do you know where I am going wrong? I think its the struct but everything I see online does what I'm doing.
You are passing a pointer to automatic storage to newly created threads: the struct values object becomes invalid as soon as the calling scope is exited, thus it cannot be reliably accessed by the new thread. You should allocate the struct values and pass the pointer to the allocated object as a parameter to pthread_create: for (int i = 0; i < threadAmount; ++i) { struct values *a = malloc(sizeof(*a)); a->arrayptr = array[i]; a->length = numberAmount / threadAmount; pthread_create(&threadid[i], NULL, thread_fn, a); } The structure can be freed by the thread function before exiting. Notes: the way you split the array into chunks only works if the length is a multiple of the number of threads. the comparison function does not work for large int values, you should use this instead: int cmpfunc(const void *a, const void *b) { return (*(int*)b < *(int*)a) - (*(int*)a < *(int*)b); }
Runtime error, input string in array
This is the input strings and the code that is supposed to read the file. When I compile using the lastest Dev C++ at home, it runs perfectly. But the Dev C++ at my school crashes the program (and after debug I know it is) at i = 9. Which is this line Michael Nguyen 71 70 91 93 28. I fixed it by changing char studentFirst[15] to char studentFirst[17]. However the name that is supposed to be put in Michael and Nguyen aren't more than 14 char each. Could someone help me take a look at it. Did I understand something wrong this line fscanf(inFile, "%s%s", studentFirst, studentLast)? Input: Sidra Amartey 90 88 70 74 70 Rebecca Brown 85 98 73 78 74 Leslie Carter 92 73 86 36 87 Ashley Guillen 95 26 90 83 85 Ryan Hilliard 75 66 69 100 52 Dawn Hopkins 84 69 66 88 74 Kyle Jiwani 7 99 96 84 89 Melvin Johnson 73 80 63 38 88 Edward Maun 82 85 72 75 99 Angelo Morrison 95 97 80 31 70 Michael Nguyen 71 70 91 93 28 Zack Nutt 82 85 97 74 98 Diana Patel 77 70 88 68 82 Patrick Perez 87 77 21 88 7 Abigail Peterson 64 81 75 85 70 Jennifer Putnam 39 91 85 80 70 Kimberly Sanjel 64 69 74 97 12 Marisa Santos 63 77 90 15 60 Hannah Shrestha 13 77 95 97 99 Linda Stoll 50 85 72 91 23 Victoria Taylor 95 93 74 63 90 Haily Wright 80 90 99 68 84 Code: int loadStudentNamesGrades(studentnode students[], const char * fileName) { FILE * inFile; char studentFirst[15] = {0}; char studentLast[15] = {0}; int numStudents = 0; int i = 0, j = 0; if((inFile = fopen(fileName, "r")) == NULL) { printf("Cannot access file %s\n", fileName); system("PAUSE"); exit(1); } for(i = 0; i < MAX_STUDENTS && (fscanf(inFile, "%s%s", studentFirst, studentLast) == 2); i++, numStudents++) { for(j = 0; j < MAX_GRADES; j++) { fscanf(inFile, "%d", &students[i].grades[j]); } students[i].name = (char*)malloc(strlen(studentFirst) + strlen(studentLast) + 2); strcpy(students[i].name, strcat(strcat(studentFirst, " "), studentLast)); } return numStudents; }
Your problem is undefined behavior. First you forget to count the terminating \0, so Michael Nguyen is actually 15 chars, not 14. However your crash is the result of the previous line there Angelo Morrison is 16 long, more than studentFirst can hold! And Abigail Peterson is 17 long, so studentFirst needs to be 17 long. studentLast only needs to be 9, but that is not a problem. It does not appear that you have understood fscanf wrong. You might not understand that strcat uses studentFirst to hold the full name.