So now I've got the warnings down to fscanf and fopen are unsafe and one other:
warning C4047: '=' : 'char' differs in levels of indirection from 'void *'
line 61, which isI'm not quite sure what that means...Code:*(a+p) = ch;
So now I've got the warnings down to fscanf and fopen are unsafe and one other:
warning C4047: '=' : 'char' differs in levels of indirection from 'void *'
line 61, which isI'm not quite sure what that means...Code:*(a+p) = ch;
Then you should use fscanf_s and fopen_s instead. The same for any other functions that gives a deprecated warning. Add "_s" to the end and supply extra arguments if needed.
They're safer functions and are therefore recommended to use.
It means you're trying to assign a char to a void* pointer. How, I don't know. First we must see the definitions of a, p and ch.warning C4047: '=' : 'char' differs in levels of indirection from 'void *'
line 61, which isI'm not quite sure what that means...Code:*(a+p) = ch;
Btw, a and p are not good variable names. They serve to confuse only, so you should avoid them.
I think I've found the problem. I'm supposed to read in 10 polynomials from a file, but there's only 9 available, so the last should be a 0. I remember someone saying that calloc creates a block of memory and clears it, so shouldn't the elements in the array just be 0? If not, how would I check to see if there is 0 polynomial or if the array is empty?
Code:int main(void) { FILE *text; int number, exp, p, k, i, go, poly1, poly2; float coeff; char again = 'Y', newFile = 'Y', operation, ch; char fileName[NAME], *polynomial[MAXPOLY], charArray[MAXPOLY], *token, *a; struct poly *first = NULL, *sum, *multiply1, *multiply2, *newLink, *pointers; while(newFile == 'Y' || newFile == 'y') { printf("\nEnter the file where the polynomials are found: \n"); fscanf(stdin, " %s", fileName); //fgets(fileName, NAME, stdin); text = fopen(fileName, "r"); /* If file failed to open, print error statement and ask for a different file. */ if(text == NULL) { printf("Error involved in opening file. Cannot open %s\n", fileName); continue; } fscanf(text, " %d", &number); /* Create an array of pointers. If error involved in allocating memory, terminate program. */ pointers = calloc(number, sizeof(struct poly)); if(pointers == NULL) { printf("Error involved in allocating space. Cannot complete task."); break; } a = &charArray[0]; ch = fgetc(text); for(k = 0; k < number; k++) { for(p = 0; ; p++) { ch = fgetc(text); *(a+p) = ch; if(ch == '\n') { *(a+p+1) = NULL; break; } } polynomial[k] = a; if(k < number - 1) { a = calloc(1,MAXPOLY*sizeof(char)); if(a == NULL) { printf("Error involved in allocating space. Cannot complete task."); exit(EXIT_FAILURE); } } } printf("\nThe polynomials available for operation are: \n"); for(i = 0; i < number; i++) { a = polynomial[i]; printf("%d. %s", i+1, a+i); } printf("\nWhat operation would you like to perform? \n1. ADD polynomials \n2. MULTIPLY polynomials \n3. EVALUATE polynomial\n"); for(;;) { printf("\nEnter choice # --> \n"); fscanf(stdin, " %c", &operation); if(operation > '3' || operation < '1') { printf("Invalid. Please select again."); continue; } break; } for(;;) { printf("Enter the polynomials you would like to work with: (#,# format)\n"); fscanf(stdin, " %d, %d", &poly1, &poly2); if(poly1 < 1 || poly2 < 1 || poly1 > number || poly2 > number) { printf("Error. Please select again."); continue; } break; } return 0; }
*(a+p+1) = NULL;
NULL is pointer *(a+p+1) is char
a[p+1] is more readable I think
and as I have said fgets is even more readable than whole this loop
You better start to check the return values of the functions you are using...
Do not forget that fgetc returns int
Each function like fscanf, fgetc,fgets could fail...
polynomial[k] = a;
your a is pointer to chararray, on the first iteration and some dynamically allocated memory on every next... The stangest mix of static and dynamic memory usage I've ever seen...
As A result I see that you don't even plan to free the allocated memory...
All problems in computer science can be solved by another level of indirection,
except for the problem of too many layers of indirection.
– David J. Wheeler
ok, new code. I'm not sure if I'm using the fgets right, since I usually get by with looping scanf("%c"...), but since the program works, I think I'm going in the right direction. I haven't freed anything since I still have to make a linked list, which is a whole other problem. At the moment, I'm trying to print out the polynomials. I've gone through, step-by-step, and the string that's stored is correct, but when the program prints out the polynomials, it cuts off the first couple of characters. So for example, from the following file, the program prints out the entire first polynomial, then leaves off the 8, the 21, and then the x^4.
Code:10 26x^5 + 5x^2 + 323x^3 + 50x^2 + 14x 8x^3 + 11x^2 + 34x + 4 21x^6 + 3x^5 + 4x + 4 x^4 + x^2 + x . . .Code:int main(void) { FILE *text; int number, exp, p, k, i, go, poly1, poly2; float coeff; char again = 'Y', newFile = 'Y', operation, ch; char fileName[NAME], *polynomial[MAXPOLY], *token, *a; struct poly *first = NULL, *sum, *multiply1, *multiply2, *newLink, *pointers; while(newFile == 'Y' || newFile == 'y') { printf("\nEnter the file where the polynomials are found: \n"); fscanf(stdin, " %s", fileName); //fgets(fileName, NAME, stdin); text = fopen(fileName, "r"); /* If file failed to open, print error statement and ask for a different file. */ if(text == NULL) { printf("Error involved in opening file. Cannot open %s\n", fileName); continue; } fscanf(text, " %d", &number); /* Create an array of pointers. If error involved in allocating memory, terminate program. */ pointers = calloc(number, sizeof(struct poly)); if(pointers == NULL) { printf("Error involved in allocating space. Cannot complete task."); break; } ch = fgetc(text); for(k = 0; k < number; k++) { a = calloc(1, MAXPOLY*sizeof(char)); fgets(a,MAXPOLY*sizeof(char),text); *(polynomial + k) = a; } printf("\nThe polynomials available for operation are: \n"); for(i = 0; i < number; i++) { a = polynomial[i]; printf("%d. %s", i+1, a+i); } printf("\nWhat operation would you like to perform? \n1. ADD polynomials \n2. MULTIPLY polynomials \n3. EVALUATE polynomial\n"); for(;;) { printf("\nEnter choice # --> \n"); fscanf(stdin, " %c", &operation); if(operation > '3' || operation < '1') { printf("Invalid. Please select again."); continue; } break; } for(;;) { printf("Enter the polynomials you would like to work with: (#,# format)\n"); fscanf(stdin, " %d, %d", &poly1, &poly2); if(poly1 < 1 || poly2 < 1 || poly1 > number || poly2 > number) { printf("Error. Please select again."); continue; } break; } printf("\nThe symbolic sum of the 2 polynomials is: "); } free(pointers); return 0; }
You want to printf a, not a+i (you're cutting off the first i characters of a that way).
Hehe, oops... Thanks!
Since the 10th polynomial doesn't exist, how would you change the empty array to 0? Could you just insert an if statement checking whether each array is "" and then replace with '0'?
The first number is supposed to be the number of polynomials in the file. So the empty string should be polynomial "0".
YAY, everything works... Thanks, everybody!!
Now, next question: What would the function header for a function that returns an array of pointers to structures and takes in an array of pointers look like?
Okay, I'm really confused about linked lists. I'm trying to add a node for each term of a polynomial containing the coefficient and the exponent, and I have no clue how to connect the new node to the end of the linked list in a for loop. I know what I have so far is wrong because I overwrite the info in current, but I don't know how to put it into newNode.
Code:struct node *make_linked_list(char *pointArray[], int N, int polyNumber) { struct node *first, *current = NULL, *newNode; char *term, *poly, sign = ' '; int i, j, num; poly = pointArray[0]; first = calloc(1,sizeof(struct node)); //beginning of the linked list first->next = current; /* Read the first term of the polynomial. From there, a new node will be created * for each term. Do this for however many polynomials are in the file. */ term = strtok(poly, ""); for(i=0; term != NULL; i++) { switch (*(term + 1)) { case '+': sign = '+'; term = strtok(NULL,""); break; case '-': sign = '-'; term = strtok(NULL,""); break; default: break; } /* Read in the coefficent and exponent of nth term in the nth polynomial. */ num = sscanf(term, "%fx^%d", ¤t->coeff, ¤t->exp); if(num == 1) { //term is nx or n num = sscanf(term, "%f%c", ¤t->coeff, ¤t->exp); if(num == 1) { current->exp = 0; } } else if(num == 0) { //term is x^n or x current->coeff = 0; num = sscanf(term, "x^%d", ¤t->exp); if(num == 0) { current->exp = 1; } } term = strtok(NULL, ""); newNode = calloc(1,sizeof(struct node)); current->next = newNode; newNode->next = NULL; } return first; }
Last edited by arrgh; 04-16-2008 at 09:30 PM.
You realize that this is complicated code that with just a little change it can become a walking timebomb, right (at least your last code)?
That mentioned, I suggest you first try to understand pointers. I did post an article a page back, too. A linked list works in a very easy way - since pointers are just addresses, it can just swap them around like it wants to. A linked list simply is like an index. One index is the head, and the last is the tail. Each index points to the next one. Each index has an address, so if something needs changing, it can just change the address of each index, without touching the actual index.