Hi pros and experts. I am experiencing some trouble in doing up a code which could evaluate the input into the different data types.

What i managed to acheived is to read a file and its content.
I used strtok to break the string into various 'tokens'.
Now the problem is how do i differentiate the tokens into the different data types. I tried using 'isdigit' and 'atoi' to no avail. help pls.

For example contents of 'myfile.txt' as follow:

12 43 + - = / -9ya -300

the program should print the output as

12 is a number.
43 is a number.
+ is a operator.
- is a operator.
/ is a operator.
-9ya is invalid.
-300 is a number.

The code i managed to acheived so far is as follows:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>


int main()
{
FILE * pFile;
char string [100];
char *tokenPtr;
int i;


pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL) perror ("Error opening file");
else {


fgets (string , 100 , pFile);
puts (string);


tokenPtr = strtok( string, " ");


while( tokenPtr != NULL ){



printf("%s\n",tokenPtr );


tokenPtr = strtok( NULL, " ");


}


fclose (pFile);
}
return 0;
}

Any help is deeply appreciated.

Recommended Answers

All 10 Replies

Well, what constitutes a number? How about an operator? Determining if the token is a valid operator is simple, just keep a list of valid operator tokens and compare the string. Numbers are harder unless you restrict yourself to the basic integers where the only valid characters are, for example, the decimal digits '0' through '9'.

>the program should print the output as
12 is a number.

You don't need to convert the string 12 to the number 12 at this stage according the the directions given above. You will need to convert the string to a number if you eventually want to do calculations using the different tokens isolated.

Doing this:

char num[] = "9ya";
int x = atoi(num);

may well give you x = 9; so you will likely need to validate first (as per Naure's post) and not just call the conversion functions atoi() or strtol() or whatever.

the problem is as follows
read content of file,
break the content into words; using strtok, delimiter is 'white space'
now the problem im facing is how do one put the 'tokenPtr' into an array?

Im thinking of, after breaking into words, but the word into one array . However im facing a problem, initializer must be constant.

After breaking each word into 'letters,numbers or operators'.
use atoi to change each 'letters,numbers or operators' into a integer. it will return a integer if integer but return 0 if it is a letter or operator.

i add all the individual parts of the array.
if array= 0, then it is not a number.
if array is 1 or more , it is a number.

another problem im facing if the number(from content of the file) is 0, it will return not a number..

i can't seem to set the content of pointer tokenPtr into another array either.

some1 help pls?

thanks in advance.

the code i come up so far.

i assume each word has a maximum of 4 size.

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>



int main()
{
   FILE * mFile; /* mFile is myfile.txt file pointer */
   char string [100]; /* string array */
   const char *tokenPtr; /* tokenPtr is a pointer to a char */


   mFile = fopen ("myfile.txt" , "r"); /* open file for reading*/
   if (mFile == NULL) perror ("Error opening file"); /*if mFile is empty, error opening file*/
   else {

     fgets (string , 100 , mFile);
     puts (string);

	 tokenPtr = strtok( string, " ");

	 while( tokenPtr != NULL ){


			printf("\n%s\n", tokenPtr );


			int i[]= atoi( tokenPtr );

				for(int a=0; a<4; a++) {
				if( i[a]*4 == 0 )
					printf("Not a number\n");
				else{
					printf("Number\n",);
				}


			tokenPtr = strtok( NULL, " ");

	}

<< moderator edit: fixed code tags: [code][/code] >>

The version I'd written after this was first (multiply-) posted pretty much followed the framework that Salem presented here. I used strtol to overcome atoi's shortcomings [edit]like zero being a valid integer as well as being an error code[/edit]. I think I chose to use a different parser that keeps the original string unmodified, but I'm away from the computer where that code is located at the moment. The operator-checking function I wrote just looped through possible strings that might match. I'd recommend using into strtol and following Salem's basic framework.

Hi guys, i like to thank all who has helped me so far. I managed to come up with some sort of code, to find the invalid string. e.g -8ha .
However im having problems getting it to print whether is it a invalid string once only. Also if there is a number in the invalid string it will print the number out too.

Also, if it is a negative number, the program will print it as invalid string too.

/*the output is .
Contents of file : 12 3 + * -79 -8ha

12 number

3 number

+ not number

* not number

-79 invalid
invalid
invalid
number

-8ha invalid
invalid
number
*/

i managed to print the positive number and operator correctly,
however i just cant seem to print the negative number and invalid string correctly.
can some1 help pls?
thanks in advance...

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>



int main()
{
  FILE * mFile;
  char string[100]; /* Input line from file           */
  char st[100];     /* Temporary storage for the line */

  char nt[4];
  char *tokenPtr;

  mFile = fopen ("myfile.txt" , "r");
  if (mFile == NULL) { /* If there was a problem, show the error */
    perror ("Error opening file");
  }
  else {
    fgets (string , 100 , mFile);
    printf("The original line: >%s<\n", string);

    strcpy(st, string);

    tokenPtr = strtok(st, " \n");

    while( tokenPtr != NULL ){
      printf("%s\n", tokenPtr);

		for( int x = 0; tokenPtr[ x ] != '\0'; x++ )
		{
			
			/* to find invalid string, e.g. -8ha*/
   			if( isalpha( tokenPtr[ x ] ) )
       		int a;
			 a = 1;


				if( isdigit( tokenPtr[ x ] ) )
				int b;
				b = 1;

					if( a == 1 && b == 1)
						{
							printf("invalid\n");
						}
		}

		/*to find number range from negative to positive and operator*/
				int i;
			i= atoi( tokenPtr );
				if( i != '\0' )
					printf(" Number\n");
				else
					{
						printf("not a number\n");
					}


      tokenPtr = strtok(NULL, " \n");
      }

  }
return 0;
}
Member Avatar for iamthwee

this may work

The version I'd written after this was first (multiply-) posted pretty much followed the framework that Salem presented here. I used strtol to overcome atoi's shortcomings [edit]like zero being a valid integer as well as being an error code[/edit]. I think I chose to use a different parser that keeps the original string unmodified, but I'm away from the computer where that code is located at the moment. The operator-checking function I wrote just looped through possible strings that might match. I'd recommend using into strtol and following Salem's basic framework.

For example,

#include <stdlib.h>
#include <string.h>

int num(const char *text)
{
   char *end;
   int result = strtol(text, &end, 10);
   return end != text && *end == '\0';
}

int op(const char *text)
{
   char *oper[] = {"+","-","*","/","="};
   size_t i;
   for ( i = 0; i < sizeof oper / sizeof *oper; ++i )
   {
      if ( strcmp(text, oper[i]) == 0 )
      {
         return 1;
      }
   }
   return 0;
}

void categorize(const char *text)
{
   printf("%s : ", text);
   if ( num(text) )
   {
      puts("number");
   }
   else if ( op(text) )
   {
      puts("operator");
   }
   else
   {
      puts("invalid");
   }
}

thanks for the help. I managed to solve the problem! :)

Since you already have a satisfactory answer, I'll post the full code that I had developed for comparison/contrast.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int num(const char *text)
{
   char *end;
   int result = strtol(text, &end, 10);
   return end != text && *end == '\0';
}

int op(const char *text)
{
   static const char *oper[] = {"+","-","*","/","="};
   size_t i;
   for ( i = 0; i < sizeof oper / sizeof *oper; ++i )
   {
      if ( strcmp(text, oper[i]) == 0 )
      {
         return 1;
      }
   }
   return 0;
}

void categorize(const char *text)
{
   printf("%s : ", text);
   if ( num(text) )
   {
      puts("number");
   }
   else if ( op(text) )
   {
      puts("operator");
   }
   else
   {
      puts("invalid");
   }
}

void parse(const char *line)
{
   const char *token = line;
   while ( *token )
   {
      char text[20];
      size_t len = strcspn(token, " \t\n\r\v");
      if ( len >= sizeof text - 1 )
      {
         len = sizeof text - 1;
      }
      sprintf(text, "%*.*s", (int)len, (int)len, token);
      categorize(text);
      token += len + 1;
   }
}

void readfile(const char *filename)
{
   FILE *file = fopen(filename, "r");
   if ( file )
   {
      char line[BUFSIZ];
      while ( fgets(line, sizeof line, file) )
      {
         parse(line);
      }
      fclose(file);
   }
}

int main(void)
{
   readfile("file.txt");
   return 0;
}

/* file.txt
12 43 + - = / -9ya -300
*/

/* my output
12 : number
43 : number
+ : operator
- : operator
= : operator
/ : operator
-9ya : invalid
-300 : number
*/

Perhaps you wouldn't mind sharing your solutiong for further review?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.