dividing polynomials into separate parts and printing their coefficients and power - c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <windows.h>
#include <conio.h>
int isnumber(char *temp) ;
void divide(char array[]);
void divide2(char array[]);
void append(char* s, char c);
int main()
{
char array[20];
scanf("%s",array);
divide2(array);
return 0;
}
int isnumber(char *temp) {
int i = 0;
int flag=0 ;
for (i=0;i<strlen(temp);i++) {
if (!isdigit(temp[i])){
flag = 1;
}
else if(temp[0]=='-' && isdigit(temp[i])){
flag=0;
}
}
return flag;
}
void divide2( char array[]){
char array1[20];
int j=0,i;
for(i=0 ; i<strlen(array1);i++)
{
array1[i]=NULL;
}
for(i=0;i<strlen(array);i++){
if(array[i]!='+'||array[i]!='-')
{
append(array1,array[i]);
j++;
}
else{
divide(array1);
for(i=0 ; i<strlen(array1);i++)
{
array1[i]='\0';
}
}
}
}
void divide(char array[]){
int co,pow,i;
char *token1;
char t[20];
char *t_3[2];
token1= strtok(array,"+");
strcpy(t,token1);
while(token1!=NULL){
t_3[0] = strtok(t,"x^");
t_3[1] = strtok(NULL,"x^");
if((t_3[0] == NULL)&&(t_3[1] == NULL)) {
co = 1;
pow = 1;
}
else if((token1[0]=='-')&& (token1[1]== 'x') && (t_3[1] != NULL)){
co=-1;
pow=atoi(t_3[1]);
}
else if ((token1[0]=='-') &&(t_3[0] != NULL)&&(t_3[1] != NULL)){
co=atoi(t_3[0]);
pow=atoi(t_3[1]);
}
else if((token1[0]=='-')&& (token1[1]== 'x') && (t_3[1] == NULL)){
co=-1;
pow=1;
}
else if(isnumber(token1)==0) {
co = atoi(t);
pow = 0;
}
else if ((t_3[0] != NULL)&&(t_3[1] == NULL) && (token1[0]=='x')){
pow = atoi(t_3[0]);
co= 1;
}
else if ((t_3[0] != NULL)&&(t_3[1] == NULL)) {
co = atoi(t_3[0]);
pow = 1;
}
else {
co = atoi(t_3[0]);
pow = atoi(t_3[1]);
}
printf("coefficient is : %d power is :%d\n",co,pow);
co=0;
pow=0;
t_3[0]='\0';
t_3[1]='\0';
for(i=0 ; i<sizeof(t);i++){
t[i]='\0';
}
token1 = strtok(NULL,"+");
if(token1==NULL){
printf("...............");
printf("\n");
}
else{
strcat(t,token1);
}
}
}
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
This code is supposed to split polynomials and print their power and coefficient but I keep getting the error undefined reference to append. Can any one tell me why? I have tried searching for this error but did not find a solution .
i fixed the problem .. but the function itself won't work

if(array[i]!='+'||array[i]!='-')
is always true. You mean (I think)
if(array[i]!='+'&& array[i]!='-')

Related

Why is there a segmentation fault in C?

I am trying to solve this:
https://www.reddit.com/r/dailyprogrammer/comments/ffxabb/20200309_challenge_383_easy_necklace_matching/
where you check if words can be rearranged by moving the last letter of one to the front(can be done multiple times) and I keep getting a segmentation fault on line 37. Does anyone know why?
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
void shift(string, int);
bool same_necklace(string a, string b)
{
if(strlen(a) != strlen(b))
{
printf("false\n");
return false;
}
int n = strlen(a);
for(int i = 0; i < n; i++)
{
shift(a, n);
if(strcmp(a, b) == 0)
{
printf("true\n");
return true;
}
}
printf("false\n");
return false;
}
void shift(string a, int n)
{
char output[n];
for(int i = 0; i < n; i++)
{
output[i] = a[(i+1) % n];
}
for(int i = 0; i < n; i++)
{
a[i] = output[i];
}
}
int main(void)
{
same_necklace("nicole", "icolen");
same_necklace("nicole", "lenico");
same_necklace("nicole", "coneli");
same_necklace("aabaaaaabaab", "aabaabaabaaa");
same_necklace("abc", "cba");
same_necklace("xxyyy", "xxxyy");
same_necklace("xyxxz", "xxyxz");
same_necklace("x", "x");
same_necklace("x", "xx");
same_necklace("x", "");
same_necklace("", "");
}
You're trying to store values to a string literal, which is read-only memory on modern OSes.
To fix it make a copy of the string you're going to shift before-hand. Remember to make room for the null-terminator and free your memory after you're done:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
void shift(string, int);
bool same_necklace(string a, string b)
{
int n = strlen(a);
a = memcpy(malloc(n + 1), a, n + 1);
if(strlen(a) != strlen(b))
{
printf("false\n");
return false;
}
for(int i = 0; i < n; i++)
{
shift(a, n);
if(strcmp(a, b) == 0)
{
printf("true\n");
return true;
}
}
printf("false\n");
free(a);
return false;
}
void shift(string a, int n)
{
char output[n];
for(int i = 0; i < n; i++)
{
output[i] = a[(i+1) % n];
}
for(int i = 0; i < n; i++)
{
a[i] = output[i];
}
}
int main(void)
{
same_necklace("nicole", "icolen");
same_necklace("nicole", "lenico");
same_necklace("nicole", "coneli");
same_necklace("aabaaaaabaab", "aabaabaabaaa");
same_necklace("abc", "cba");
same_necklace("xxyyy", "xxxyy");
same_necklace("xyxxz", "xxyxz");
same_necklace("x", "x");
same_necklace("x", "xx");
same_necklace("x", "");
same_necklace("", "");
}

Creating list of ip addresses over a specific range in C

I am writing a tool to scan all the nodes on a network but I have ran in to a problem. I'm writing the tool in C but I'm new to the language so I'm not sure how the iterate through the address range.
The user will give the argument 192.168.*.* and it will create every IP address in that range, e.g. 192.168.1.1, 192.168.1.2, 192.168.1.3 and then eventually 192.168.2.1, 192.168.2.2, 192.168.2.3 etc.
My previous code was:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void scanner(int s)
{
char addr[20];
for (int i = 0; i < 255; ++i)
{
sprintf(addr, "192.168.%d.%d", s, i);
printf("%s\n", addr);
}
}
int main()
{
for (int i = 0; i < 255; ++i)
{
scanner(i);
}
return 0;
}
But I don't know how to run this from the user input.
You can take the inputs from the user using the scanf function. I have updated your code to use the same -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int addr_byte_0;
int addr_byte_1;
void scanner(int s)
{
char addr[200];
int i;
for (i = 0; i < 255; ++i)
{
sprintf(addr, "%d.%d.%d.%d", addr_byte_0, addr_byte_1, s, i);
printf("%s\n", addr);
}
}
int main()
{
int i;
//printf("Enter the first byte of the address: ");
scanf ("%d", &addr_byte_0);
//printf("Enter the second byte of the address: ");
scanf ("%d", &addr_byte_1);
for (i = 0; i < 255; ++i)
{
scanner(i);
}
return 0;
}
Also, as per C standards you cannot declare a variable inside the for loop. Hence I have moved the declaration out of the for loop. Hope this helps!
Inspired by (e.g. python-) generators, my solution doesn't perform dynamic memory allocation and and has constant memory consumption. I don't like that I currently rely on a do while loop. Also the explicit check for ig->num_wildcards == 0 is ugly. Anyways:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define IP_OCTETS 4
#define MAX_UCHAR 255
typedef struct {
int wildcard_pos[IP_OCTETS];
int num_wildcards;
int counter[IP_OCTETS];
int octet[IP_OCTETS];
} ip_generator;
char* mystrsep(char** stringp, const char* delim)
{
char* start = *stringp;
char* p;
p = (start != NULL) ? strpbrk(start, delim) : NULL;
if (p == NULL)
{
*stringp = NULL;
}
else
{
*p = '\0';
*stringp = p + 1;
}
return start;
}
void init_ip_gen(ip_generator *ig, char* ip_mask)
{
char *token, *string;
char* ip_mask_ptr = ip_mask;
const char delimiters[] = ".";
int i = 0;
while ((token = mystrsep(&ip_mask_ptr, delimiters)) != NULL)
{
ig->wildcard_pos[i] = -1;
if (strcmp(token, "*") == 0)
{
ig->wildcard_pos[ig->num_wildcards] = i;
ig->counter[ig->num_wildcards] = 1;
ig->num_wildcards++;
}
else
{
ig->octet[i] = atoi(token);
}
i++;
}
}
int ig_next(ip_generator *ig)
{
int i;
int carry = 1;
if (ig->num_wildcards == 0)
{
return 0;
}
for (i = ig->num_wildcards - 1; i >= 0; i--)
{
if (carry == 1)
{
if (ig->counter[i] == MAX_UCHAR)
{
ig->counter[i] = 1;
}
else
{
ig->counter[i]++;
carry = 0;
}
}
if (carry == 0)
{
break;
}
if (i == 0 && carry == 1)
{
return 0;
}
}
return 1;
}
void generate_ip(ip_generator *ig, char *ip)
{
int i;
int j = 0;
int oct[IP_OCTETS];
for (i = 0; i < IP_OCTETS; i++)
{
if (i == ig->wildcard_pos[j])
{
oct[i] = ig->counter[j];
j++;
}
else
{
oct[i] = ig->octet[i];
}
}
sprintf(ip, "%d.%d.%d.%d", oct[0], oct[1], oct[2], oct[3]);
}
int main()
{
char ip_mask[] = "192.*.10.*";
//char ip_mask[] = "192.1.10.123";
ip_generator ig;
memset(&ig, 0, sizeof(ig));
init_ip_gen(&ig, ip_mask);
char ip[32];
memset(ip, 0, sizeof(ip));
do
{
generate_ip(&ig, ip);
printf("%s\n", ip);
} while (ig_next(&ig));
return 0;
}

Palindrome finder in C?

I'm trying to make a palindrome finder in C and I don't know where it is going wrong, no matter what I get the output false on the 2 different ways that I have tried to code this. I have only just started C (in the past week) so if you could explain things simply that'd be great, thanks!
//way1
#include <stdio.h>
int read_char() { return getchar(); }
void read_string(char* s, int size) { fgets(s, size, stdin); }
void print_char(int c) { putchar(c); }
void print_string(char* s) { printf("%s", s); }
int is_palin(char word[]) {
int m = 0;
int arr_len = sizeof(word) / sizeof(char); //change to char_index
int n = arr_len;
int t = 1;
if(n % 2 != 0) {
for (m=0; m < ((n-1)/2); m++) {
if(word[m] != word[n-m-2]) {
t = 0;
}
else {
t = 1;
}
}
}
else {
for (m=0; m < (n/2)-1; m++) {
if(word[m] != word[n-m-2]) {
t = 0;
}
else {
t = 1;
}
}
}
if(t == 1) {
return 1;
}
else {
return 0;
}
}
int main(void) {
char word[6] = "civic";
int arr_len = sizeof(word)/sizeof(char);
if (is_palin(word) == 1) {
printf("is palin\n");
}
else {
printf("is not palin\n");
}
printf(word);
printf("\n");
printf("%d\n", arr_len);
return 0;
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//way2
#include <stdio.h>
int read_char() { return getchar(); }
void read_string(char* s, int size) { fgets(s, size, stdin); }
void print_char(int c) { putchar(c); }
void print_string(char* s) { printf("%s", s); }
int is_palin(char word[]) {
int m = 1;
int input_length = sizeof(word);
int j = input_length-1;
int i = 0;
for(i=0; i <= j; i++) {
if(word[i] != word[j]) {
m = 0;
j--;
}
}
if(m == 1) {
return 1;
}
else {
return 0;
}
}
int main(void) {
char word[6] = "civic";
int input_length = sizeof(word);
if (is_palin(word) == 1) {
printf("is palin\n");
}
else {
printf("is not palin\n");
}
printf(word);
printf("\n");
printf("%d\n", input_length);
return 0;
}
Please try this, it works fine.
#include <stdio.h>
int main( )
{
int flag = 0;
int length = 0;
int len2 = 0;
int i = 0;
char name[130];
char p[130];
char q[130];
printf( "please enter a name or sentence\n" );
scanf( "%[^\n]", name );
length = strlen( name );
len2 = length;
strcpy( p, name );
memset( q, '.', length ); // handy to debug comparaison
q[length] = '\0';
for ( i = 0; i < length; i++ )
{
q[--len2] = p[i];
}
printf( "\n p==%s", p );
printf( "\n q==%s", q );
getchar( );
if ( !strcmp( p, q ) )
flag = 1;
if ( flag == 1 )
printf( "\npalindrome\n" );
else
printf( "\nnot a palindrome\n" );
return 0;
}
Take a look at this code, that's how I have implemented it (remember to #include <stdbool.h> or it will not work):
for(i = 0; i < string_length; i++)
{
if(sentence[i] == sentence[string_lenght-1-i])
palindrome = true;
else
{
palindrome = false;
break;
}
}
Doing that it will check if your sentence is palindrome and, at the first occurence this is not true it will break the for loop. You can use something like
if(palindrome)
printf(..);
else
printf(..);
for a simple prompt for the user.
Example :
radar is palindrome
abba is palindrome
abcabc is not palindrome
Please , pay attention to the fact that
Abba
is not recognized as a palindrome due to the fact that ' A ' and 'a' have different ASCII codes :
'A' has the value of 65
'a' has the value of 97
according to the ASCII table. You can find out more here.
You can avoid this issue trasforming all the characters of the string to lower case characters.
You can do this including the <ctype.h> library and calling the function int tolower(int c); like that :
for ( ; *p; ++p) *p = tolower(*p);
or
for(int i = 0; str[i]; i++){
str[i] = tolower(str[i]);
}
Code by Earlz, take a look at this Q&A to look deeper into that.
EDIT : I made a simple program to do this, see if it can help you
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
void LowerCharacters(char *word, int word_lenth);
int main(void){
char *word = (char *) malloc(10);
bool palindrome = false;
if(word == 0)
{
printf("\nERROR : Out of memory.\n\n");
return 1;
}
printf("\nEnter a word to check if it is palindrome or not : ");
scanf("%s", word);
int word_length = strlen(word);
LowerCharacters(word,word_length);
for(int i = 0; i < word_length; i++)
{
if(word[i] == word[word_length-1-i])
palindrome = true;
else
{
palindrome = false;
break;
}
}
palindrome ? printf("\nThe word %s is palindrome.\n\n", word) : printf("\nThe word %s is not palindrome.\n\n", word);
free(word);
return 0;
}
void LowerCharacters(char *word, int word_length){
for(int i = 0; i < word_length; i++)
word[i] = tolower(word[i]);
}
Input :
Enter a word to check if it is palindrome or not : RadaR
Output :
The word radar is palindrome.

read char from txt file is wrong

Hello guys please help me to understand something !
I have a txt file and I read different values. I'm doing it successfully but I have an ASCII too, ie. KS98B2
I am trying to read it and store it in a value. Could you please have a look at my code? The word "KS98B2" should be stored at the variable "name". So I declare it in the main as a char. Do you agree?
Inside the "asc" function there is a putchar, and it is printed properly, I checked that, I receive KS98B2.
But, inside the asc function printf gives the value : 84122658
And inside main printf gives the value: 24
Yes, I put %d in printf and name is a char, but how is it possible that the variable is not the same ? How can I make it work? Please help me !
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
FILE *file;
char ch;
int asc(char eow, bool *eof) {
int var = 0;
while((ch=fgetc(file))!=EOF) {
putchar(ch);
if ((ch >= 'A') && (ch <= 'Z')) {
var <<= 4;
var += (ch - 'A' + 65);
}
else if ((ch >= '0') && (ch <= '9')) {
var <<= 4;
var += (ch - '0');
} else if (ch == eow) {
return var;
} else {
puts("Incorrect syntax.\n");
}
}
putchar('\n');
printf("Var inside asc %d\n", var);
}
int main() {
char name;
bool eof = false;
if ((file = fopen("messages.txt", "r")) == NULL) {
puts("WRONG FILE\n");
return 1;
}
while(!feof(file)) {
name= asc('\n', &eof);
printf("Var main: %d\n", name);
}
fclose(file);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
FILE *file;
//char ch;//There is no need to be a global variable
int asc(char eow, bool *eof) {
int var = 0;
int ch;//Type in order to compare the EOF and value must be int
while((ch=fgetc(file))!=EOF) {
if(isupper(ch))
var = var * 36 + (ch - 'A' + 10);
else if(isdigit(ch))
var = var * 36 + (ch - '0');
else if (ch == eow)
return var;
else {
fprintf(stderr, "\nIncorrect syntax.\n");
}
}
*eof = true;
return var;
}
int main(void) {
int name;//It must be int to receive the value of int
bool eof = false;
if ((file = fopen("messages.txt", "r")) == NULL) {
puts("WRONG FILE\n");
return 1;
}
while(!feof(file)) {
name= asc('\n', &eof);
printf("Var main: %d\n", name);
}
fclose(file);
return 0;
}
void putdecimal(int name) {
int i=0;
int var = name;
int array[30];
int cnt = 0;
while(var){
array[cnt++] = var % 36;
var /= 36;
}
for(i = cnt-1; i>=0; i--){
if(array[i]<10)
putchar(array[i] + '0');
else
putchar(array[i] - 10 + 'A');
}
}
Example to store the read characters into an array.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
FILE *file;
char *gasc(int size, char buff[size], char eow){
int i = 0, ch = 0;
while(i < size - 1 && (ch=fgetc(file))!=EOF && ch != eow){
if (isupper(ch) || isdigit(ch)){
buff[i++] = ch;
} else {
fprintf(stderr, "\nIncorrect syntax.\n");
}
}
buff[i] = '\0';
if(i == 0 && ch == EOF)
return NULL;
return buff;
}
int main(void) {
char name[20];
if ((file = fopen("messages.txt", "r")) == NULL) {
puts("WRONG FILE\n");
return 1;
}
//is_eof is no longer necessary to represent NULL return value of gasc instead of EOF.
while(gasc(sizeof(name), name, '\n') != NULL) {
printf("'%s'\n", name);
}
fclose(file);
return 0;
}

Loop with simple counter malfunctioning?

I have a program that takes a char array and calls the function convert. The function determines whether the character is a letter or number. The program is supposed to output the first letter it finds in the string. and the first numbers it finds in the string. My loop to stop looking for letters after it finds one isn't working.
Any thoughts?
Code is written in C using the Borland Compiler.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int convert (char array[],char **);
int main()
{
int intval;
char array[512], *charptr;
printf("Input a string that starts with a series of decimal digits:\n>");
while ( gets( array ) != NULL ){
intval = convert(array, &charptr );
printf ("Intval contains %d, Charptr contains '%s'\n", intval, charptr);
}
system("pause");
return 0;
}
int convert (char array[],char ** charptr)
{
int i, x, c = 0;
char b[512];
for (i=0;i<strlen(array);i++){
if (isalpha(array[i]))
{
if(c >= 1){
*charptr = &array[i];
c++;
}
else
break;
}
else if ( isdigit(array[i]))
x = 10*x + array[i] - '0';
}
return x;
}
UPDATE:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int convert (char array[],char ** charptr);
int main()
{
int intval;
char array[512], *charptr;
printf("Input a string that starts with a series of decimal digits:\n>");
while ( gets( array ) != NULL ){
intval = convert(array, &charptr );
printf ("Intval contains %d, Charptr contains '%s'\n", intval, charptr);
}
system("pause");
return 0;
}
int convert (char array[],char ** charptr)
{
int i, x, c;
char b[512];
for (i=0;array[i] != 0;i++){
if ( isdigit(array[i]))
x = 10*x + array[i] - '0';
else if (isalpha(array[i]))
{
c++;
if(c >= 1){
*charptr = &array[i];
}
}
}
return x;
}
You have a logic error. c is initialized to 0. There is a line to increment c but it is inside an if block that will never be true.
if(c >= 1){
*charptr = &array[i];
c++;
}
Catch 22???
Perhaps you meant to use:
int convert (char array[],char ** charptr)
{
int i, x, c = 0;
char b[512];
for (i=0;i<strlen(array);i++){
if (isalpha(array[i]))
{
// No need for checking the value of c
// return as soon you find an alphabet.
*charptr = &array[i];
break;
}
else if ( isdigit(array[i]))
// If you are looking for an alphabet only,
// why do you have this block of code???
x = 10*x + array[i] - '0';
}
return x;
}
Update
Perhaps, this is what you are looking for.
int convert (char array[], char ** charptr)
{
size_t i;
int x = 0;
size_t len = strlen(array);
// Set charptr to NULL in case there are no letters in the input.
*charptr = NULL;
for (i=0;i<len;i++){
if ( isalpha(array[i]))
{
*charptr = &array[i];
return x;
}
else if ( isdigit(array[i]))
{
x = 10*x + array[i] - '0';
}
}
return x;
}
int scanString(char array[],char * charptr)
{
int len = strlen(array);
int digs = 0;
int x = 0;
*charptr = 0;
for (int i=0;i<len;i++){
if (charptr == 0 && isalpha(array[i]))
{
*charptr = array[i];
}
else if (digs == 0 && isdigit(array[i])){
x = array[i] - '0';
digs = 1;
}
if(digs > 0 && charptr != 0)
break;
}
return x;
}
the spec says return the first character found so changed the charptr.

Resources