aeroxr1
aeroxr1

Reputation: 1074

converting from string to int using strtol() : \0' or '\n'?

I have a doubt with conversion from string to int. I got a string through function fgets then I used strtol function to convert it to int. This is the code :

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

int main(void)
{
  char buf[BUFSIZ];
  char *p = NULL;
  long int val;
  int numero;
  int temp;

  do
  {
temp=0;
printf ("Enter a number: ");
if (fgets(buf, sizeof(buf), stdin) != NULL)
{
    val = strtol(buf, &p, 10);
    if(buf==p)
    {
        printf(" no digits \n");
        temp=1;
    }
    if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val   == 0)) 
    {
        perror("strtol");
        temp=1;
    }
    if (*p != '\0')
    {
        printf("you have insert any char character \n");
        temp=1;
    }
 }
else
 {
    printf("Error\n");
    temp=1;
 }   
}
while(temp == 1);

 /* If we got here, strtol() successfully parsed a number */
 numero=(int)val;
 printf("***** The number is : %d ******* \n",numero);

return 0;
}

and this code doen't work, but it work if I replace this control

if (*p != '\0')
    {
        printf("you have insert any char character \n");
        temp=1;
    }

with this one :

if (*p != '\n')
    {
        printf("you have insert any char character \n");
        temp=1;
    }

Do you know why ? :)

EDIT : This is the code of my final function version :) Thanks to all :) Now it seem that all correctly works :

int readIN(int *numero)  
{
   long int val;
   char buf[BUFSIZ];
   char *p = NULL;

   if (fgets(buf, sizeof(buf), stdin) != NULL)
   {
      val = strtol(buf, &p, 10);
      if(buf==p)
      {
        return 1;
      }
    if ( (val > INT_MAX || val < 0) || (errno != 0 && val == 0)) 
    {
           return 1;
            }
    if (*p != '\n' && *p != '\r' && *p != '\0')
    {
         return 1;
    }
  }
  else
  {
    return 1;
  }  

  *numero=(int)val;
  return 0;  
}

Upvotes: 0

Views: 4078

Answers (1)

ams
ams

Reputation: 25599

Your code works perfectly. It has correctly identified that there are trailing characters after the number. As Matt says, gets returns a whole line, including the trailing line feed character (aside: why do people insist on posting the actual answer as a comment?).

Given that your string will almost always have this line feed, your simple fix is probably the right thing to do.

There are two exceptions though:

  1. end of file
  2. operating systems that use carriage returns at the end of line.

A more thorough solution would be this:

if (*p != '\n' && *p != '\r' && *p != '\0')
    {
        printf("error: unexpected trailing characters in input\n");
        temp=1;
    }

Upvotes: 4

Related Questions