I am currently working on an exercise for algorithm class. I was asked to write a C program which adds two polynomials entered by the user, which, I am able to do by asking the user the highest degrees of each polynomial and their coefficients.
The problem is that the input of the user must be something like for example -5x4+2x2+6
(all coefficients and degrees can go from 0
to 9
).
I managed to convert this string to an array
void tableau(char *chaine) {
int i = 0;
while (1) {
scanf("%c", &chaine[i]);
if (chaine[i] == '\n') {
break;
} else {
i++;
}
}
}
And I created a structure
struct polynome {
int coeff;
int degre;
};
I can't find a way to convert this array to a polynomial, here are all the functions I have written to make it work but I always get weird outputs:
int DEGREMAXTAB(char TAB[]) {
int i = 0;
int degre0 = 0;
while (TAB[i] != '\0') {
if (TAB[i] == 'x' && (int)(TAB[i+1]) > degre0)
degre0 = (int)(TAB[i+1]);
i++;
}
return degre0; // it returns the right highest degree + 48 for some reason, I don't know
}
void tabpoly(char chaine[], int degre0, struct polynome polynome[]) {
int k = 1;
int i = 0, a = 0, b = 0;
while (chaine[i]) { // I am sorry, all of this is really messy, I just tried
if (chaine[i] == '\0')
break;
if (chaine[i] == '-') {
k = -1;
i++;
}
if (chaine[i] == '+') {
k = 1;
i++;
}
if (chaine[i] != 'x') {
a = k * ((int)(chaine[i]));
i++;
}
i++;
b = ((int)(chaine[i]));
polynome[degre0].coeff = a;
polynome[degre0].degre = b;
degre0++;
i++;
}
}
void afficher(struct polynome poly[], int degre0) { /* maybe something is wrong here too I
really can't find the issue except by tweaking everything and causing other issues */
int i = 0;
char signe;
for (i = degre0; i >= 0; i--) {
if (poly[i].coeff < 0) {
signe = '\0';
} else {
signe = '+';
}
printf("%c%dx%d", signe,poly[i].coeff, poly[i].degre);
}
}
My main so far :
int main(int argc, const char *argv[]) {
struct polynome poly1[6]; // the maximum degree is 5
int deg1 = 0, i = 0;
char chainea[21];
printf("Entrez votre premier polynôme\n");
tableau(chainea);
while (chainea[i] != '\0') {
printf("%c",chainea[i]);
i++;
} // did this to check that there was no problem here
deg1 = DEGREMAXTAB(chainea);
printf("%d\n", deg1); // same, except that I must return deg1-48 and idk why
tabpoly(chainea, deg1, poly1);
afficher(poly1, deg1);
}
I know my code might be really messy and I apologize for that, I would be glad if someone here could help me figure this out. Here is the output I have when typing the input from the example.
Entrez votre premier polynôme
-5x4+2x2+6
-5x4+2x2+6
4
-101x4+0x0+0x0+0x0+0x1Program ended with exit code: 0
Entrez votre premier polynôme
2x2
2x2
2
+2x2+0x0+0x1Program ended with exit code: 0
Thank you really much, I tried to put as much information as I could. :)
There are multiple problems in your code:
fgets()
instead of reading one character at a time with scanf()
. scanf()
is not the best tool for that.48
is digits are ASCII characters, not integer values. You must subtract the value of '0'
(which as the value 48
in ASCII) to get the corresponding number.poly
array beyond the maximum index value because of the 48 offset. You should check that the exponent is within the proper range.poly
array is uninitialized.Here is a modified version:
#include <stdio.h>
struct polynome {
int coeff;
int degre;
};
int degremaxtab(const char tab[]) {
int i, exp, max_exp = 0;
for (i = 0; tab[i] != '\0'; i++) {
if (tab[i] == 'x') {
i++;
if (tab[i] >= '0' && tab[i] <= '9') {
exp = tab[i] - '0';
} else {
exp = 1;
}
if (max_exp < exp) {
max_exp = exp;
}
}
}
return max_exp;
}
int skip_spaces(const char chaine[], int i) {
while (chaine[i] == ' ' || chaine[i] == '\t' || chaine[i] == '\n') {
i++;
}
return i;
}
/* return the maximum exponent in the polynomial */
int tabpoly(const char chaine[], struct polynome polynome[], int max_degree) {
int i, max_exp, sign, coeff, exp;
for (i = 0; i <= max_degree; i++) {
polynome[i].coeff = 0;
polynome[i].degre = i;
}
i = 0;
max_exp = 0;
while (chaine[i] != '\0') {
i = skip_spaces(chaine, i);
// get sign (allow +-)
sign = 1;
if (chaine[i] == '+') {
i++;
}
i = skip_spaces(chaine, i);
if (chaine[i] == '-') {
sign = -1;
i++;
}
i = skip_spaces(chaine, i);
if (chaine[i] >= '0' && chaine[i] <= '9') {
coeff = chaine[i] - '0';
i++;
} else {
coeff = 1;
}
if (chaine[i] == 'x') {
i++;
if (chaine[i] >= '0' && chaine[i] <= '9') {
exp = chaine[i] - '0';
i++;
} else {
exp = 1;
}
} else {
exp = 0;
}
i = skip_spaces(chaine, i);
// check for a complete term
if (chaine[i] != '\0' && chaine[i] != '+' && chaine[i] != '-')
return -2; // syntax error
if (exp > max_degree)
return -1; // exponent too large
if (max_exp < exp)
max_exp = exp;
polynome[exp].coeff += sign * coeff;
}
return max_exp;
}
void afficher(struct polynome poly[], int degre0) {
int i, pos;
/* simple output */
for (i = degre0; i >= 0; i--) {
printf("%+dx%d", poly[i].coeff, poly[i].degre);
}
printf("\n");
/* clean output */
pos = 0;
for (i = degre0; i >= 0; i--) {
int coeff = poly[i].coeff;
int degre = poly[i].degre;
if (coeff != 0) {
if (coeff > 0) {
if (pos > 0)
pos += printf("+");
if (coeff != 1 || degre == 0)
pos += printf("%d", coeff);
} else {
if (coeff != -1 || degre == 0)
pos += printf("%d", coeff);
else
pos += printf("-");
}
if (degre > 0) {
printf("x");
if (degre > 1)
pos += printf("%d", degre);
}
}
}
if (pos == 0) {
printf("0");
}
printf("\n");
}
int main(int argc, const char *argv[]) {
struct polynome poly1[6]; // the maximum degree is 5
char chainea[100];
int deg1;
printf("Entrez votre premier polynôme\n");
// read a full line from stdin
if (!fgets(chainea, sizeof(chainea), stdin))
return 1;
deg1 = degremaxtab(chainea);
printf("exposant maximum: %d\n", deg1);
deg1 = tabpoly(chainea, poly1, 5);
if (deg1 < 0) {
if (deg1 == -1)
printf("exposant trop grand\n");
else
if (deg1 == -2)
printf("erreur de syntaxe\n");
else
printf("erreur\n");
} else {
afficher(poly1, deg1);
}
return 0;
}