Hi,
I am reading in strings and integers and I am wondering, am I doing this correctly where I will prevent overflow problems and also not have a bunch of issues with my strings? Since I started messing with C, I have had tremendous problems getting this stuff to work and I think I got it now. I am just wondering how to improve the code I wrote.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
void read(char *out, const int size);
int readint(int *out);
void readdouble(double *out);
int main(void)
{
char buffer[17] = {0};
int i = 0;
double d = 0;
printf("read string[16]: ");
read(buffer, 17);
printf("read integer: ");
if(!readint(&i)) {
printf("the number you entered is beyond the range allowable, please try again.");
while(!readint(&i)) {
printf("the number you entered is beyond the range allowable, please try again.");
}
}
printf("read: %s\t\t%d\n\n", buffer, strlen(buffer));
printf("readint: %d\n\n", i);
printf("readint: %5.2f\n\n", d);
system("PAUSE");
return 0;
}
/**
function: read
purpose: reads in a string and assigns it to out. Requires a length of
string parameter of n+1 (+1 allows for null terminator).
args: char *out, const int strlen
returns: void
*/
void read(char *out, const int strlen)
{
char ch;
int char_count = 0;
// Read in the keyboard input until enter is pressed or
// we exceed the buffer. We will not allow the buffer
// to overflow by restricting what actually gets written
// to the pointer.
ch = getchar();
*(out)++ = ch;
while(ch != '\n' && ++char_count < strlen-1) {
ch = getchar();
if(char_count < strlen-1)
*(out)++ = ch;
}
// Null terminate the pointer so it is a proper string
*out = '\0';
// Flush the remaining keyboard input
fflush(stdin);
}
/**
function: readint
purpose: reads an integer and assigns it to the out pointer parameter.
defines: INT_LEN
args: int *out
returns: int (1 success, -1 error)
*/
#define INT_LEN 100
int readint(int *out)
{
char buf[INT_LEN]; /* buffer for retriving an int */
char tmpbuf[INT_LEN]; /* temporary buffer for reconverting the int to a string to check for integer overflow */
int i, tmpbuflen, buflen;
read(buf, INT_LEN); /* read input from the user as a string */
i = atoi(buf); /* convert the string to an int */
// Reconvert to a string to ensure that the conversion didn't cause an integer overflow
itoa(i, tmpbuf, 10);
tmpbuflen = strlen(tmpbuf);
buflen = strlen(buf) - 1; /* subtract 1 for the null terminator, otherwise comparison will fail */
if(tmpbuflen != buflen || INT_MIN < i && i > INT_MAX) // check if they are the same and within signed integer ranges
return 0;
*out = i;
return 1;
}