i am trying to take a string and seeing if it could be converted into decimal/float/octal/hex
I have stored these strings into an array, and im iterating through them and checking which element is what.
for(int k=0;k<i;k++){
char* string = tokenArray[k];
fprintf(newFile, "Tokens are: %s\n", string);
if(checkDecimal(string) == 1){
result[k] = "Decimal"; printf("Token: %s is %s\n", string, result[k]);
}
else if(checkFloat(string) == 1){
result[k] = "Float"; printf("Token: %s is %s\n", string, result[k]);
}
else if(checkHex(string) == 1){
result[k] = "Hex"; printf("Token: %s is %s\n", string, result[k]);
}
else if(checkOctal(string) == 1){
result[k] = "Octal"; printf("Token: %s is %s\n", string, result[k]);
}
else {
printf("Token: %s Did not work\n", string);
}
I wrote contents of my array into a separate file which is, :
fprintf(newFile, "Tokens are: %s\n", string);
Tokens are: 012
Tokens are: 23948
Tokens are: 1.21e+19
Tokens are: [
Tokens are: ,
Tokens are: 0
Tokens are: 0x56
Tokens are: 888
Tokens are: 0X11
Tokens are: 12
Tokens are: 333
Tokens are: 234
Tokens are: 012
Tokens are: 12
Tokens are: 01200
As you can see i am getting the tokens correctly, but my output is coming up weird.
This is my code for checking elements:
int checkFloat(char *s){
char *str = NULL;
long i = strtol(s, &str, 0);
if (!*str)
return 0;
if (*str == 'e' || *str == 'E' || *str == '.')
return 1;
return 0;
}
int checkHex(char *s){
char *str = s;
if((*str) == '0'){
if((*(str++) == 'x')){
printf("%s\n", "olala");
}
}
if(*(str) == 0 && (*(str++) == 'x' || *(str++) == 'X'))
{
printf("%s\n", "ok");
while(*(str) != '\0')
{
if (!isxdigit(*str))
{
return 0;
}
++str;
}
return 1;
}
return 0;
}
int checkOctal(char *s){
char *str = s;
if (*str != '0')
{
return 0;
}
while (isdigit(*str) && *str != '8' && *str != '9')
{
if(*(++str) == '\0')
{
return 1;
}
str++;
}
return 0;
}
int checkDecimal(char *s){
char *str = s;
if(*str == '0')
return 0;
for(int i=0;i<strlen(str);i++){
if(str[i] < 49 || str[i] > 57)
return 0;
}
return 1;
}
I think these functions are fine,
this is the output:
Token: 012 is Octal
Token: 23948 is Decimal
Token: 1.21e+19
is Float
Token: [ Did not work
Token: , Did not work
Token: 0 is Octal
Token: 0x56 Did not work
Token: 888 is Decimal
Token: 0X11
Did not work
Token: 12 is Decimal
Token: 333 is Decimal
Token: 234
Did not work
Token: 012
Did not work
Token: 12 is Decimal
Token: 01200 is Octal
As you can see, first token was 012 which came out as octal (fine). Another token with same 012 came out as error. Same with "234".
I dont know why my hex fucntion dosent work either.
Plz help
Your code's most outstanding issue is your use of '++' (increment). You tend to overuse it, skipping over characters you intend to test. E.g. consider a clause like:
(*(str) == 0 && (*(str++) == 'x' || *(str++) == 'X'))
Which can leave the pointer in two different locations and fails to test for 'X' as it's looking at the wrong character. This really should be:
(*str++ == '0' && (*str == 'x' || *str == 'X'))
Your code is riddled with this type of error. (As well as confusing 0 with '0' as noted in the comments.) Fixing your increments and generally reworking your code:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
typedef enum { FALSE = 0, TRUE } boolean;
int checkFloat(char *s) {
char *extra = NULL;
(void) strtol(s, &extra, 0);
return ((*extra != '\0') && (*extra == 'e' || *extra == 'E' || *extra == '.'));
}
int checkHex(char *s) {
char *str = s;
if (*str++ == '0' && (*str == 'x' || *str == 'X')) {
while (*(++str) != '\0') {
if (!isxdigit(*str)) {
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
int checkOctal(char *s) {
char *str = s;
if (*str++ != '0') {
return FALSE;
}
while (isdigit(*str) && *str != '8' && *str != '9') {
if (*(++str) == '\0') {
return TRUE;
}
}
return FALSE;
}
int checkDecimal(char *s) {
char *str = s;
if (*str == '0') {
return FALSE; // looks like octal
}
for (size_t i = 0; i < strlen(str); i++) {
if (str[i] < '1' || str[i] > '9') {
return FALSE;
}
}
return TRUE;
}
char *tokenArray[] = {
"012",
"12948",
"1.21e+19",
"[",
",",
"0",
"0x56",
"888",
"0X11",
"12",
"333",
"234",
"012",
"12",
"01200"
};
#define TOKEN_COUNT (sizeof(tokenArray) / sizeof(char *))
int main() {
char *result[TOKEN_COUNT];
for (size_t k = 0; k < TOKEN_COUNT; k++) {
char *string = tokenArray[k];
if (checkDecimal(string)) {
result[k] = "Decimal";
printf("Token: %s is %s\n", string, result[k]);
} else if(checkFloat(string)) {
result[k] = "Float";
printf("Token: %s is %s\n", string, result[k]);
} else if (checkHex(string)) {
result[k] = "Hex";
printf("Token: %s is %s\n", string, result[k]);
} else if (checkOctal(string)) {
result[k] = "Octal";
printf("Token: %s is %s\n", string, result[k]);
} else {
printf("Token: %s Did not work\n", string);
}
}
return 0;
}
Produces:
Token: 012 is Octal
Token: 12948 is Decimal
Token: 1.21e+19 is Float
Token: [ Did not work
Token: , Did not work
Token: 0 Did not work
Token: 0x56 is Hex
Token: 888 is Decimal
Token: 0X11 is Hex
Token: 12 is Decimal
Token: 333 is Decimal
Token: 234 is Decimal
Token: 012 is Octal
Token: 12 is Decimal
Token: 01200 is Octal
In general, style-wise, you should pick an indentation/bracketing style you like and stick with it consistenly -- your code is all over the place.
Related
I am writing a program that translates letters into morse code and then transmits them to an LED and blinks. I am not able to return the value ".- -..."
#include <stdio.h>
#include <string.h>
char *encode()
{
char *name = "AB";
char name_m[100] = "";
for (int i = 0; i < strlen(name); i++)
{
if (name[i] == 65)
{
strcat(name_m, ".- ");
}
else if (name[i] == 66)
{
strcat(name_m, "-...");
}
};
printf("%s", name_m);
return name_m;
}
int main()
{
char *name_m;
name_m = encode();
printf("\n%s", name_m);
}
main.c:22:10: warning: function returns address of local variable [-Wreturn-local-addr]
22 | return name_m;
| ^~~~~~
.- -...
(null)
In C you cant return reference (pointer) to local variable as it stops to exist when function returns.
You need to pass te buffer to the function:
char *encode(char *name_m, const char *name)
{
for (int i = 0; i < strlen(name); i++)
{
if (name[i] == 'A')
{
strcat(name_m, ".- ");
}
else if (name[i] == 'B')
{
strcat(name_m, "-...");
}
}
printf("%s", name_m);
return name_m;
}
allocate it dynamically:
char *encode( const char *name)
{
char *name_m = malloc(100);
if(name_m)
{
for (int i = 0; i < strlen(name); i++)
{
if (name[i] == 'A')
{
strcat(name_m, ".- ");
}
else if (name[i] == 'B')
{
strcat(name_m, "-...");
}
}
printf("%s", name_m);
}
return name_m;
}
or the worst solution - define it as static
char *encode( const char *name)
{
static char name_m[100];
if(name_m)
{
for (int i = 0; i < strlen(name); i++)
{
if (name[i] == 'A')
{
strcat(name_m, ".- ");
}
else if (name[i] == 'B')
{
strcat(name_m, "-...");
}
}
printf("%s", name_m);
}
return name_m;
}
So, essentially I have two files:
File 1:
//
// main.c
// frederickterry
//
// Created by Rick Terry on 1/15/15.
// Copyright (c) 2015 Rick Terry. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int size (char *g) {
int ofs = 0;
while (*(g+ofs) != '\0') {
++ofs;
}
return ofs;
}
int parse(char *g) {
// Setup
char binaryConnective;
int negated = 0;
// Looking for propositions
int fmlaLength = size(g);
if(fmlaLength == 0) {
return 1;
}
if(fmlaLength == 1) {
if(g[0] == 'p') {
return 1;
} else if (g[0] == 'q') {
return 1;
} else if (g[0] == 'r') {
return 1;
} else {
return 0;
}
}
// Now looking for negated preposition
if(fmlaLength == 2) {
char temp[100];
strcpy(temp, g);
if(g[0] == '-') {
negated = 1;
int negatedprop = parse(g+1);
if(negatedprop == 1) {
return 2;
}
}
}
// Checking if Binary Formula
char arrayleft[50];
char arrayright[50];
char *left = "";
char *right = "";
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
if(fmlaLength != 1 && fmlaLength != 2) {
if(g[0] == '-') {
int negatedBinary = parse(g+1);
if(negatedBinary == 1 || negatedBinary == 2 || negatedBinary == 3) {
return 2;
} else {
return 0;
}
}
int i = 0;
int l = 0;
int p = strlen(g);
for(l = 0; l < strlen(g)/2; l++) {
if(g[l] == '(' && g[p-l-1] == ')') {
i++;
}
}
for(int q = i; q < strlen(g); q++) {
if(g[q] == '(') {
numLeft++;
} else if(g[q] == ')') {
numRight++;
}
arrayleft[q] = g[q];
//printf("%c", arrayleft[i]);
//printf("%s", left);
if((numRight == numLeft) && (g[q+1] == 'v' || g[q+1] == '>' || g[q+1] == '^')) {
arrayleft[q+1] = '\0';
bclocation = q+1;
binaryConnective = g[q+1];
binarypresent = 1;
// printf("The binary connecive is: %c\n", binaryConnective);
break;
}
}
if(binarypresent == 0) {
return 0;
}
int j = 0;
for(int i = bclocation+1; i < strlen(g)-1; i++) {
arrayright[j] = g[i];
j++;
}
arrayright[j] = '\0';
left = &arrayleft[1];
right = &arrayright[0];
//printf("Printed a second time, fmla 1 is: %s", left);
int parseleft = parse(left);
// printf("Parse left result: %d\n", parseleft);
if(parseleft == 0) {
return 0;
}
int parseright = parse(right);
if(parseright == 0) {
return 0;
}
// printf("Parse right result: %d\n", parseleft);
if(negated == 1) {
return 2;
} else {
return 3;
}
}
return 0;
}
int type(char *g) {
if(parse(g) == 1 ||parse(g) == 2 || parse(g) == 3) {
if(parse(g) == 1) {
return 1;
}
/* Literals, Positive and Negative */
if(parse(g) == 2 && size(g) == 2) {
return 1;
}
/* Double Negations */
if(g[0] == '-' && g[1] == '-') {
return 4;
}
/* Alpha & Beta Formulas */
char binaryConnective;
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
bclocation = i+1;
binaryConnective = g[i+1];
binarypresent = 1;
break;
}
}
}
/* Connective established */
if(binaryConnective == '^') {
if(g[0] == '-') {
return 3;
} else {
return 2;
}
} else if(binaryConnective == '>') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
} else if (binaryConnective == 'v') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
}
}
return 0;
}
char bin(char *g) {
char binaryConnective;
char arrayLeft[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
int j = 0;
arrayLeft[j++] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[i+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
return binaryConnective;
}
}
}
return binaryConnective;
}
char *partone(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
for(int k = bclocation+1; k < strlen(g)-1; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
int k = 0;
k++;
return leftSide;
}
char *parttwo(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
int n = size(g) - 1;
if(g[strlen(g)-1] != ')') {
n++;
}
for(int k = bclocation+1; k < n; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
char* rightSide = &arrayRight[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
return rightSide;
}
char *firstexp(char *g) {
char* left = partone(g);
char leftArray[50];
int i = 0;
for(i; i < strlen(left); i++) {
leftArray[i] = left[i];
}
leftArray[i] = '\0';
char binConnective = bin(g);
int typeG = type(g);
if(typeG == 2) {
if(binConnective == '^') {
return &leftArray;
} else if(binConnective == '>') {
return &leftArray;
}
} else if(typeG == 3) {
if(binConnective == 'v')
return &leftArray;
}
char temp[50];
for(int i = 0; i < strlen(leftArray); i++) {
temp[i+1] = leftArray[i];
}
temp[0] = '-';
char* lefttwo = &temp[0];
if(typeG == 2) {
if(binConnective == 'v') {
return lefttwo;
}
} else if(typeG == 3) {
if(binConnective == '>' || binConnective == '^') {
return lefttwo;
}
}
return "Hello";
}
char *secondexp(char *g) {
// char binaryConnective = bin(g);
// char* right = parttwo(g);
// char rightArray[50];
// int i = 0;
// for(i; i< strlen(right); i++) {
// rightArray[i+1] = right[i];
// }
// rightArray[i] = '\0';
// int typeG = type(g);
// if(type(g) == 2) {
// if(binaryConnective == '^') {
// return &rightArray;
// }
// } else if(type(g) == 3) {
// if(binaryConnective == 'v' || binaryConnective == '>') {
// return &rightArray;
// }
// }
return "Hello";
}
typedef struct tableau tableau;
\
\
struct tableau {
char *root;
tableau *left;
tableau *right;
tableau *parent;
int closedbranch;
};
int closed(tableau *t) {
return 0;
}
void complete(tableau *t) {
}
/*int main(int argc, const char * argv[])
{
printf("Hello, World!\n");
printf("%d \n", parse("p^q"));
printf("%d \n", type("p^q"));
printf("%c \n", bin("p^q"));
printf("%s\n", partone("p^q"));
printf("%s\n", parttwo("p^q"));
printf("%s\n", firstexp("p^q"));
printf("Simulation complete");
return 0;
}*/
File 2:
#include <stdio.h>
#include <string.h> /* for all the new-fangled string functions */
#include <stdlib.h> /* malloc, free, rand */
#include "yourfile.h"
int Fsize = 50;
int main()
{ /*input a string and check if its a propositional formula */
char *name = malloc(Fsize);
printf("Enter a formula:");
scanf("%s", name);
int p=parse(name);
switch(p)
{case(0): printf("not a formula");break;
case(1): printf("a proposition");break;
case(2): printf("a negated formula");break;
case(3): printf("a binary formula");break;
default: printf("what the f***!");
}
printf("\n");
if (p==3)
{
printf("the first part is %s and the second part is %s", partone(name), parttwo(name));
printf(" the binary connective is %c \n", bin(name));
}
int t =type(name);
switch(t)
{case(0):printf("I told you, not a formula");break;
case(1): printf("A literal");break;
case(2): printf("An alpha formula, ");break;
case(3): printf("A beta formula, ");break;
case(4): printf("Double negation");break;
default: printf("SOmewthing's wrong");
}
if(t==2) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
if(t==3) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
tableau tab;
tab.root = name;
tab.left=0;
tab.parent=0;
tab.right=0;
tab.closedbranch=0;
complete(&tab);/*expand the root node then recursively expand any child nodes */
if (closed(&tab)) printf("%s is not satisfiable", name);
else printf("%s is satisfiable", name);
return(0);
}
If you look at the first file, you'll see a method called * firstexp(char * g).
This method runs perfectly, but only if another method called * secondexp(char * g) is commented out.
If * secondexp(char * g) is commented out, then *firstexp runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is -(pvq), second expansion fmla is Hello
((pvq)>-p) is satisfiableProgram ended with exit code: 0
otherwise, if *secondexp is not commented out, it runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is \240L, second expansion fmla is (-
((pvq)>-p) is satisfiable. Program ended with exit code: 0
As you can see, the outputs are completely different despite the same input. Can someone explain what's going on here?
In the commented-out parts of secondexp and in parttwo, you return the address of a local variable, which you shouldn't do.
You seem to fill a lot of ad-hoc sized auxiliary arrays. These have the problem that they might overflow for larger expressions and also that you cannot return them unless you allocate them on the heap with malloc, which also means that you have to free them later.
At first glance, the strings you want to return are substrings or slices of the expression string. That means that the data for these strings is already there.
You could (safely) return pointers into that string. That is what, for example strchr and strstr do. If you are willing to modify the original string, you could also place null terminators '\0' after substrings. That's what strtok does, and it has the disadvantage that you lose the information at that place: If you string is a*b and you modify it to a\0b, you will not know which operator there was.
Another method is to create a struct that stores a slice as pointer into the string and a length:
struct slice {
const char *p;
int length;
};
You can then safely return slices of the original string without needing to worry about additional memory.
You can also use the standard functions in most cases, if you stick to the strn variants. When you print a slice, you can do so by specifying a field width in printf formats:
printf("Second part: '%.*s'\n", s->length, s->p);
In your parttwo() function you return the address of a local variable
return rightSide;
where rightSide is a pointer to a local variable.
It appears that your compiler gave you a warning about this which you solved by making a pointer to the local variabe arrayRight, that may confuse the compiler but the result will be the same, the data in arrayRight will no longer exist after the function returns.
You are doing the same all over your code, and even worse, in the secondexp() function you return a the address of a local variable taking it's address, you are not only returning the address to a local variabel, but also with a type that is not compatible with the return type of the function.
This is one of many probable issues that your code may have, but you need to start fixing that to continue with other possible problems.
Note: enable extra warnings when compiler and listen to them, don't try to fool the compiler unless you know exactly what you're doing.
I write program which sort numbers like 23.44 12.4223. And almost everything works fine but it does not sort correctly numbers for instance 24.321 and 24.33 i mean for my rpgoram 24.321 is greater than 24.33
Infile contains numbers like 34.5 123.55. 56. .43 564.3
Here's my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define NUMBER_CHUNK 13
char* getNumber(FILE* fp)
{
int length;
int current = 0;
int c;
char *number, *number2;
number = (char*)malloc(sizeof(char)*NUMBER_CHUNK);
if(!number)
{
printf("Error while allocating memory!\n");
return NULL;
}
length = NUMBER_CHUNK;
while(!isspace(c = fgetc(fp)) && !feof(fp))
{
if(isdigit(c) || c == '.')
{
number[current] = c;
current++;
if(current >= length)
{
length+=NUMBER_CHUNK;
number2 = (char*)realloc(number,sizeof(char*)*length);
if(number2 == NULL)
{
free(number2);
return NULL;
}
else number2 = number;
}
}
else
{
return NULL;
}
}
number[current] = '\0';
return number;
}
int compare(const void *str1, const void *str2)
{
char* curr1;
char* curr2;
int value = 0;
size_t len1 = 0;
size_t len2 = 0;
curr1=*(char**)str1;
curr2=*(char**)str2;
while(*curr1=='0' || *curr1=='.') curr1++;
while(*curr2=='0' || *curr2=='.') curr2++;
while(*curr1 || *curr2)
{
while(*curr1 == '.')
curr1++;
while(*curr2 == '.')
curr2++;
if(value == 0)
{
value = *curr1 - *curr2;
}
if(*curr1)
{
curr1++;
len1++;
}
if(*curr2)
{
curr2++;
len2++;
}
}
if(len1 != len2)
{
return (len1 > len2) ? 1 : -1;
}
return value;
}
int main(int argc, char** argv)
{
FILE* fp;
char** tab;
int i = 0;
int lines = 0;
int length = 10;
if(argc != 2)
{
printf("Incorrent syntax! Use ./program_name input_file\n");
return 1;
}
if(!(fp = fopen(argv[1],"r")))
{
printf("Could not open the file! Please try again!\n");
return 2;
}
tab = (char**)malloc(length*(sizeof(char*)));
if(!tab)
{
printf("Could not allocate memory!\n");
free(tab);
return 3;
}
while(!feof(fp))
{
tab[i] = getNumber(fp);
if(i >= length)
{
length += 10;
tab = (char**)realloc(tab,sizeof(char*));
if(tab == NULL)
{
free(tab);
return 5;
}
}
if(tab[i] == NULL)
{
printf("Incorrect character in the infile! Terminating\n");
free(tab);
return 4;
}
if(*tab[i] == '\0')
{
free(tab[i]);
i--;
}
i++;
lines = i;
}
printf("\nBEFORE\n");
for(i = 0 ; i < lines; i++)
{
printf("%s\n", tab[i]);
}
qsort(tab, lines, sizeof(char*), compare);
printf("\nAFTER\n");
for(i = 0; i < lines; i++)
{
printf("%s\n",tab[i]);
free(tab[i]);
}
printf("\n");
free(tab);
fclose(fp);
return 0;
}
In your program 24.321 is greater than 24.33 because length of 24.321 is greater than length of 24.33.
You should stop increasing length when you read ..
Fix:
//UPDATE
while(*curr1=='0') curr1++;
while(*curr2=='0') curr2++;
//END OF UPDATE
char dot1 = 0, dot2 = 0;
char err1 = 0, err2 = 0;
while(*curr1 || *curr2)
{
if(*curr1 == '.') ++dot1; //UPDATE2
if(*curr2 == '.') ++dot2; //UPDATE2
while(*curr1 == '.')
curr1++;
while(*curr2 == '.')
curr2++;
if(value == 0)
{
value = *curr1 - *curr2;
}
if(*curr1)
{
if(*curr1 < '0' || *curr1 > '9') err1 = 1;
curr1++;
if(!dot1) len1++;
}
if(*curr2)
{
if(*curr2 < '0' || *curr2 > '9') err2 = 1;
curr2++;
if(!dot2) len2++;
}
}
if(err1 || err2 || dot1 > 1 || dot2 > 1) exit(1); // UPDATE2
UPDATE:
I updated code. Now before main comparison while only zeros are skipped. Dots will be skipped at the beginning of main while and fix with dot1 and dot2 will work.
UPDATE2:
To check if numbers are correct you should count dots and check if all chars are dots or digits.
Be aware that for longer bad numbers (more than 255 dots) my code could not work correctly (because dot1 is 1 byte long). If you need to handle these cases you should check if dot1/dot2 are equal to 1 and change err1/err2 to 1 instead of increasing dot1/dot2.
Your problem is here:---
if(len1 != len2)
{
return (len1 > len2) ? 1 : -1;
}
For strings "24.321" len1 = 6 ,"24.33" len2 = 5 so the longest string wins.
I thing your algorithm will also encounter problems with 123.45 vs 23.456 as you are basically ignoring the decimal point.
You could try converting to floating point (use function atof() or strtof() ) to convert the string to a real real number then compare.
Or simply return "less than" if you encounter a '.' in the first string before you encounter it in the second string.
Can't figure this out, any help? I don't think this is strtok, I pretty sure it is my code. I can't figure out what thought. Get and Set are causing sigsevg. If I put a printf() after num = strtof, etc, the num is right, but the other commands arent being interpreted right.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
float height;
float width;
float length;
}Box;
void usage(void)
{
printf("\nUsage: [command] [parameter] [amount]\n");
printf("commands:\n\tSet\n\tGet\n");
printf("parameters:\n\theight\n\twidth\n\tlength\n");
}
int main()
{
usage();
Box box1 = {0,0,0};
int loop = 1;
float num;
char cp[65], *delims = " !##$%^&*():;/><.,\\?\"";
char *tok1, *tok2, *tok3, *temp;
beginning:
while(loop)
{
//Read the command from standard input
char str[65];
fgets(str, 64, stdin);
str[64] = 0;
//Tokenize the string
strncpy(cp, str, 64);
tok1 = strtok(cp, delims);
tok2 = strtok(NULL, delims);
tok3 = strtok(NULL, delims);
//Check if tok3 is float
num = strtof(tok3, &temp);
if(num != 0)
{
}
else
{
usage();
goto beginning;
}
if(tok1 == 'Get' && tok2 == 'height')
{
printf("%f", box1.height);
}
else if(tok1 == 'Get' && tok2 == 'width')
{
printf("%f", box1.width);
}
else if(tok1 == 'Get' && tok2 == 'length')
{
printf("%f", box1.length);
}
else if(tok1 == 'Get')
{
usage();
goto beginning;
}
if(tok1 == 'Set' && tok2 == 'height')
{
box1.height = num;
printf("%f", box1.height);
}
else if(tok1 == 'Set' && tok2 == 'width')
{
box1.width = num;
}
else if(tok1 == 'Set' && tok2 == 'length')
{
box1.length = num;
}
else if(tok1 == 'Set')
{
usage();
goto beginning;
}
}
return 0;
}
if(tok1 == 'Get' && tok2 == 'height')
C strings have to use double quotes, and you can't test them equal using ==, you should use strcmp:
if(strcmp(tok1, "Get")==0 && strcmp(tok2, "height")==0)
About strtof:
num = strtof(tok3, &temp);
If you didn't have to use temp, use a null pointer:
num = strtof(tok3, NULL);
And the piece of code using goto:
if(num != 0)
{
}
else
{
usage();
goto beginning;
}
goto is ugly, use continue instead:
if(num == 0)
{
usage();
continue;
}
int sum_s1=0, sum_s2=0;
int comps(char s1[], char s2[]) {
if (s1[0] == '\0' && s2[0] == '\0') {
if (sum_s1 == sum_s2) {
printf("hihi"); //printable
return 1; //return the 4202692
} else {
return 0;
}
} else {
if (*s1 != '\0') {
if (s1[0]!=32) {
sum_s1 += s1[0];
} else {
sum_s1 += 0;
}
*s1 = *(s1+1);
}
if (*s2 != '\0') {
if (s2[0]!=32) {
sum_s2 += s2[0];
} else {
sum_s2 += 0;
}
*s2 = *(s2+1);
}
if (*s1 != '\0' && *s2 == '\0') equalIgnoreSpace(s1+1, "\0");
if (*s1 == '\0' && *s2 != '\0') equalIgnoreSpace("\0", s2+1);
if (*s1 != '\0' && *s2 != '\0') equalIgnoreSpace(s1+1, s2+1);
if (*s1 == '\0' && *s2 == '\0') equalIgnoreSpace("\0", "\0");
}
}
int main() {
int compa=1;
compa = comps("abc f", "abcf");
printf("%d", compa); //return the 4202692
if (compa == 1) {
printf("Two string are equal");
} else {
printf("Two string are not equal");
}
getchar();
return 0;
}
comps() should return 1 and stop, but I can't get 1 in main function. How can I fix this?
there is no return statement in the comps function [in else case]
int comps(char s1[], char s2[])
{
if (s1[0] == '\0' && s2[0] == '\0')
{
if (sum_s1 == sum_s2)
{
printf("hihi"); //printable
return 1; //return the 4202692
}
else
return 0;
}
else
{
...
...
return code;
}
}
You're trying to modify a static string with *s1 = *(s1+1); and your program crashes. Try with this instead:
int main() {
int compa=1;
/* Allocated memory can be modified without adverse effects! */
char s1[64];
char s2[64];
strcpy(s1, "abc f");
strcpy(s2, "abcf");
compa = comps(s1, s2);
printf("%d", compa); //return the 4202692
if (compa == 1) {
printf("Two string are equal");
} else {
printf("Two string are not equal");
}
getchar();
return 0;
}
Also, as mentioned by Sourav, comps is missing return statements. Compiling it gives:
1>c:\code\test\test.cpp(83): warning C4715: 'comps' : not all control paths return a value
And compa will have an undefined value assigned to it once you assign it the (undefined) return value of comps.