Read() integer in c - c

I tried code below, but the results aren't correct. I think that something with size of buffer can be implemented in a wrong way.
int f(int* as) {
*as = read(STDIN_FILENO, as, sizeof(int));
} //i print 123
int s;
f(&s);
printf("%d",s); // prints 4

Two things that prevent the program to give the result you expect
1) using read to read from standard input (characters) and store that into a (binary) integer
2) storing the result of read into that same integer, overwriting the (wrong) value stored in 1)
Have a look at scanf or fgets (atoi...), to read into a character array (string), then convert the characters read into a binary number, for instance
char str[20];
fgets(str, 20, stdin);
int s = atoi(str);
read version
char str[20];
ssize_t nread = read(STDIN_FILENO, str, 20);
int s = atoi(str);
See what an integer is,

Related

reading and printing unsigned int from file

I am trying to print and read unsigned ints from a .txt file. I am using fprintf to print the unsigend int, (menualy checking the file presents the wanted values), but when reading it, I get a weird offset to all the values I read (same offset beween all reads, but not every run of the program), here is the reading code I am using:
unsigned int tempDuration = (unsigned int)fileFgets(file);
and this is fileFgets:
char tempStr[MAX_STR_SIZE] = { 0 };
char* str = 0;
fgets(tempStr, MAX_STR_SIZE, file);
tempStr[strcspn(tempStr, "\n")] = 0;
str = (char*)malloc(strlen(tempStr) * sizeof(str));
strcpy(str, tempStr);
return str;
I am using this function becuse it is ment to read both strings and unsinged ints, seperated by '\n', but am open for using diffrent solutions for both or either. (reading the strings works as intended)
Casting from an array of characters to an unsigned integer will actually cast the pointer and not the string itself. You need to convert it using strtoul().
Replacing the '\n' character isn't required because strtoul stopps at the first character which is not a valid digit.
I modified your function :
unsigned int fileFgets(file)
{
char tempStr[MAX_STR_SIZE] = { 0 };
fgets(tempStr, MAX_STR_SIZE, file);
return strtoul(tempStr, NULL, 0);
}

Casting string to int in C

I am trying to find out what this casting operation do:
char w[12] = {0};
int r;
r = (int)gets(w);
When input is for example 156, the value of r is -1073744588, so it is not a simple conversion to integer.
What your code does is cast the return value of gets, which is a pointer to the first character of the user input string, into an int. In other words, you are putting the address of the string into an integer, r. However, the address is so high that it "wraps around" in the integer r, yielding the large negative value.
You are most likely trying to convert the user's input into an int. This is the code to do so
char buf[80];
int res;
if (fgets(buf, sizeof buf, stdin)) /* load input into buf */
if (sscanf(buf, "%d\n", &res) < 1) /* try to read integer from buf */
fprintf(stderr, "Bad input\n"); /* input was bad; write error */
Notice, you should never use gets because it has serious security problems. Use fgets instead to read a line from the standard input.

strtok and int vs char in C

I am learning how to delimate char arrays and I need to do an operation where I split a number and string into different variables and print them out. I believe I am close but when printing out what should be my number I get crazy numbers. Is this the address to the int? Any advice is greatly appreciated! My code and input/output:
#include <stdio.h>
int main() {
setbuf(stdout, NULL);
char name[10];
printf("Enter in this format, integer:name\n");
fgets(name, 10, stdin); //my input was 2:brandon
char *n = strtok(name, ":");
int num = (int)n;
char * order = strtok(NULL, ":");
printf("%d,%s", num,order); //my output was 7846332,brandon
return (0);
}
This line is incorrect:
int num = (int)n;
Is this the address to the int?
No, it is an address of the character buffer at the position where the character representation of your integer is stored, re-interpreted as an int (i.e. it may be a truncated address, making it pretty much a meaningless number).
You can convert it to int either by parsing the value, or using atoi:
int num = atoi(n);
Demo.
If you give e.g. "123:foobar" as input, the pointer n points to the string "123". When you cast the pointer to an integer, the value of the integer is the value of the variable n which is the address of where in memory the string returned by strtok is located.
If you want to convert a string containing a number to an actual number, you should use e.g. the strtol function:
int num = strtol(n, NULL, 10);

Entering different types (in C)

I'm attempting to prompt the user to enter several numbers and, when the user enters a string, the program calculates the sum of those numbers. I'm having difficulty because I want to keep the program as simple as possible without creating other variables to store strings, etc.
int menu(int choice){
int total = 0, values = 0;
char *string = (char*) &values;
switch(choice){
case 1: printf("Enter your values separated by a whitespace: ");
while(string != "compute") {
scanf("%d",&values);
total = total + values;
}
}
return total;
}
I want the user to enter as many numbers as s/he wants (obviously within memory limits), so I have to continually anticipate an int (or other "number"), so what's the most effective way to also anticipate a string?
I know that the following line is a bit sketchy, but why exactly if I want the variable "string" to treat "values" like a string/char type?
char *string = (char*) &values;
To read a string you have to allocate some space for it. You cannot read it into an integer.
To support reading input that could be either an integer or a string, you have to read a string; and then you can try to convert the string to integer.
For example:
char buffer[50];
scanf("%49s", buffer);
if ( 0 == strcmp(buffer, "compute") )
return 0; // they typed "compute"
if ( 0 == sscanf(buffer, "%d", &number) )
break; // they typed something that was not a number
total += number;
When you write like this
int total = 0, values = 0;
char *string = (char*) &values;
You set the pointer string to point to the integer value values so if the user enters a value that is larger than sizeof(values) i.e. sizeof(int), the program will crash.
Instead use a dedicated buffer for the input string
char string[128] = {0};
scanf can be used for input but it is safer to use fgets() to minimize the risk of a buffer overrun:
fgets( string, sizeof(string), stdin );
if you need to hold the individual values entered declare an array of ints e.g.
int values[100];
when the user has enters something check the content of 'string' and see if it
contains compute - it may be enough checking the first char - e.g. if ( string[0] == 'c' ) else convert the string to int and place it in the array of values:
values[i++] = atoi(string);
EDIT:
As McNabb pointed out fgets() adds a \n to the string so if you want to compare the whole string you must take that into account e.g.
if ( !strncmp( "compute", string, strlen("compute") )
{...}
The most efficient method would be to read in a string (use fgets()), then try to decide what it is. If it's an integer, you can use atoi or strtol to convert it. If it's a float, you can use strtod. Otherwise, you can parse the string however you want.
So you'll end up with something like this:
char str[15];
long sum = 0, val;
char* ptr;
while (1)
{
fgets(str, 15, stdin);
if (0 == strcmp(str, "compute"))
{
printf("sum: %d\n", sum);
break;
}
val = strtol(str, &ptr, 10);
// error-check here.
sum += val;
}
Another, simpler option, might be to read integers (using scanf, as in your code above) until end-of-file, then print the sum. That approach has some limitations: you need to give your input through some channel that has a defined EOF, and you can't receive more input after the end of your list of integers. Use a specific value (such as 0) as a sentinel, as Havenard suggested, does not have these drawbacks, but doesn't allow the sentinel value to appear in your list of numbers either.
Not sure why are you trying to compare strings at this point. If you just want to read whitespace separated integers until a non-integer value is entered, let scanf do the work for you:
int menu(int choice){
int total = 0;
int value;
switch(choice){
case 1: printf("Enter your values separated by a whitespace: ");
while(scanf("%d",&value) > 0) {
total += value;
}
}
/* Here, use scanf to get the first non-integer value entered */
return total;
}

Conversion from Byte to ASCII in C

Can anyone suggest means of converting a byte array to ASCII in C? Or converting byte array to hex and then to ASCII?
[04/02][Edited]: To rephrase it, I wish to convert bytes to hex and store the converted hex values in a data structure. How should go about it?
Regards,
darkie
Well, if you interpret an integer as a char in C, you'll get that ASCII character, as long as it's in range.
int i = 97;
char c = i;
printf("The character of %d is %c\n", i, c);
Prints:
The character of 97 is a
Note that no error checking is done - I assume 0 <= i < 128 (ASCII range).
Otherwise, an array of byte values can be directly interpreted as an ASCII string:
char bytes[] = {97, 98, 99, 100, 101, 0};
printf("The string: %s\n", bytes);
Prints:
The string: abcde
Note the last byte: 0, it's required to terminate the string properly. You can use bytes as any other C string, copy from it, append it to other strings, traverse it, print it, etc.
First of all you should take some more care on the formulation of your questions. It is hard to say what you really want to hear. I think you have some binary blob and want it in a human readable form, e.g. to dump it on the screen for debugging. (I know I'm probably misinterpreting you here).
You can use snprintf(buf, sizeof(buf), "%.2x", byte_array[i]) for example to convert a single byte in to the hexadecimal ASCII representation. Here is a function to dump a whole memory region on the screen:
void
hexdump(const void *data, int size)
{
const unsigned char *byte = data;
while (size > 0)
{
size--;
printf("%.2x ", *byte);
byte++;
}
}
Char.s and Int.s are stored in binary in C. And can generally be used in place of each other when working in the ASCII range.
int i = 0x61;
char x = i;
fprintf( stdout, "%c", x );
that should print 'a' to the screen.

Resources