Using atoi, grabbing integer from string - c

#include<stdio.h>
#include<conio.h>
#include<string.h>
int main() { {
char sir[3000];
int i;
int suma = 0;
int lungime;
scanf("%s", sir);
lungime = strlen(sir);
char x;
char *pX;
x = sir[2];
pX = &x;
suma = atoi(pX);
return 0;
}
I am doing the adventOfCode, Day1.
My problem is that I cannot pick certain digits from the string, using atoi.
From what I read, atoi needs a pointer as argument.
if i read some big string like "111555434536563673673567367...."
with a length between 2000 - 3000
I can't understand why when I print "suma", instead of printing the certain digit from my string, it prints some huge integer, like 83506.

From what I read, atoi needs a pointer as argument.
Needing a pointer is only part of the deal. The other part is that the pointer needs to point to a null-terminated string representing an integer.
Moreover, x = sir[2]; pX = &x is not how you get a pointer to the second element of sir[] array: x is a copy of the third digit (arrays are zero-based), and pX is a pointer to that copy.
If you want to get a numeric value of a single digit, subtract '0' from it (note single quotes around zero):
int thirdDigitVal = sir[2] - '0';
If you need to do it with atoi, copy the digit into a null-terminated string:
char copy[2] = {0};
copy[0] = sir[2];
int thirdDigitVal = atoi(copy);

Related

Variable storage from character to integer pointer is not retrieving data properly

In below program why data of character printed properly in normal int variable case and why it is not printing the data properly in int?
Case 1
#include <stdio.h>
int main()
{
int *i = NULL;
char s = 'A';
i = (int *)&s; // storing
printf("i - %d\n",*i);
return 0;
}
Output :
i - 1837016897
Why 65 value not printed here?
Case 2
#include <stdio.h>
int main()
{
int *i = NULL;
char s = 'A';
i = (int *)&s; // storing
printf("i - %c\n",*i); // if we display character stored here
// then it is printed properly
return 0;
}
Output:
i - A
Case 3
#include <stdio.h>
int main()
{
int i = 0;
char s = 'A';
i = s;
printf("i - %d\n",i); // in this case data is properly printing
return 0;
}
Output:
i - 65
int is 4 bytes long, char is 1 byte. This means that you cannot convert like this. You are taking the pointer of a 1-byte variable and are telling the program to interpret it like a 4-byte variable, so whatever is behind it in the memory will also be used in the program.
1837016897 in hexadecimal value becomes 0x6D7EA741, where the last byte (0x41) is actually decimal 65, so the character does show up in your result (if you're wondering why it is the last byte and not the first, this is because of endianness - you can read up on that yourself if you like).
Your programs 1 and 2 exhibit undefined behaviour because they refer to an object of type char via an lvalue of type int. This is not allowed according to section 6.5 paragraph 7 of the standard.
Your program 3 is OK because char is implicitly converted to int when passed to a function like printf, which is perfectly normal and well-defined.
i = (int *)&s;
this makes sure i points to the address of s, but since s is char and i is int* when dereferencing i, (*i) the compiler looks for int type unless using cast like so ( *(char*)i ), so it looks at the address of s, but looks at 4 bytes instead of 1 (assuming 32-bit int)
int requires 4 bytes to be stored in memory while char requires only 1 byte to be stored in memory. So char s = 'A' stores only one byte with value 65 at memory address &s.
In case 1, you try to print 4 bytes at the memory address pointed by &s as am integer. Now the memory adjacent to &s may have garbage values hence, you get 1837016897 instead of 65.
In case 2, you are printing using %c which recasts i into a char and hence prints only one byte.
In case 3, i=s stores the value of s i.e. 65 into i, hence you get 65 as the output.

Extract an integer value from array and program without showing printf function

I want to extract a number from an array I introduce in the keyboard and convert it into one integer. My code is:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
int r, t, i;
char expressio[t];
char vector[50];
char rpn[t][4];
printf("Introduce the expresssion");
fgets(expressio, t, stdin);
t = strlen(expressio);
for (i = 0; i <= t; i++) {
if (isdigit(expressio[i])) {
r = atoi(expressio[i]);
vector[i] = rpn[0][r];
}
return 0;
}
}
I have this warning:
passing argument 1 of 'atoi' makes pointer from integer without a cast
How can i solve it?
Also, when I execute this program, it does nothing and it doesn't even print the "Introduce the expression". Why is this happening?
That warning means that you are passing a bad argument to the function. "atoi" is expecting an array of chars as argument, but you are passing a single char as argument here:
r = atoi(expressio[i]);
If you want to convert a single char into a number, you can do:
r = expressio[i] - '0';
If you look at the ascii table, you will notice that the ascii value of 0 is 48. If you substract 48 (or, like i did, the ascii value of 0) to your char expressio[i], you will get the corresponding number as an integer. Like this, if expressio[i] equals '8', then r will equal 8.

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);

Store an integer in a char array

I am trying to store an integer in a char array. How can I do that? This is my approach (by casting it the int to a char) but it does not work. What am I missing?
#include <stdio.h>
int main(int argc, char** argv)
{
char cArray[10] = {};
// Store a character in the char array
cArray[5] = 'c';
printf("%c\n", cArray[5]);
// Store an integer in the char array
cArray[6] = (char) 0; // WHY DOES THIS NOT WORK???
printf("%c\n", cArray[6]);
}
Let's start with the basics.
For x86 architecture(assuming you use it) a char variable is stored in 1 byte and an int variable is stored in 4 bytes.
It is IMPOSSIBLE to store a random integer value in a char variable unless you have some compression schema and know that some integer values will not occur(no random!) in your program. No exceptions.
In your case, you want to store integers in a char array. There are four options:
1.If you want to store a random integer in this char array, then you should get the pointer to the index that you want to store the integer and cast it to an integer pointer and use it like that.
char mychars[10];
int * intlocation = (int*)(&mychar[5]);
*intlocation = 3632; // stores 3632
Beware that this will write to 4 bytes(4 char locations in your array) starting from the index you have specified. You should always check you are not going out of array.Also you should do the same casting for retrieving the value when needed.
2.If your values are between [0,255] or [-128,127] you can safely store your integers in a char since these ranges can be represented using a byte. Beware that char being signed or unsigned is implementation-dependent. Check this out!
mychars[5] = 54;
3.If your integer is just a digit, you can use the char representation of the digit.
mychars[5] = your_digit + 48; // 48 is the ascii code for '0'
4.If you want to store the string representation of your integer, then you should use itoa() and write each char of the resulting string to your array one by one. In that case, you should always check that you are not going out of array.
cArray[6] = (char) 0; // WHY DOES THIS NOT WORK???
printf("%c\n", cArray[6]);
This code attempts to print a character with the encoding 0; assuming ASCII, nothing will get displayed because there is no printable character associated with that code.
If you intend to store the ASCII code for the character '0' and print it, then you need to write
cArray[6] = 48; // same as writing cArray[6] = '0' (ASCII)
printf( "%c\n", cArray[6] );
This will print 0 to your console.
If, on the other hand, you want to store any arbitrary integer value1 to cArray[6] and display that value, then you need to use the %d conversion specifier:
cArray[6];
printf( "%d\n", cArray[6] );
1. That is, any integer that fits into the range of char, anyway
Normally, a computer exactly does what you tell it. The instruction DWIM (do what I mean) hasn't been invented yet.
cArray[6] = (char) 0; // WHY DOES THIS NOT WORK???
sets the index position 6, but
printf("%c\n", cArray[5]);
prints the index position 5.
I would like to add on to Seçkin Savaşçı's answer (in which you cast a char* pointer to somewhere in the char array to an int* pointer, allowing you to write an integer to the array by dereferencing the pointer).
You can also use bit-shifting:
#include <stdio.h>
int main() {
int first_int = 4892; // number larger than 127 (max. value of char)
int second_int = 99584; // same
// char array to hold two integers:
char array[8]; // ...assuming an integer size of 4 and char size of 1
// Now, assuming you are on a little endian system (in which the least
// significant bytes come first), you can add the two above integers to the
// array like so:
array[0] = first_int; // assigns first_int's least significant byte
array[1] = first_int >> 8; // assigns first_int's 2nd least significant byte
array[2] = first_int >> 16; // assigns first_int's 2nd most significant byte
array[3] = first_int >> 24; // assigns first_int's most significant byte
// repeat for second_int:
array[4] = second_int;
array[5] = second_int >> 8;
array[6] = second_int >> 16;
array[7] = second_int >> 24;
// You can now prove that this char array holds the two integers like this:
printf("First integer: %d\n", *((int *) array));
printf("Second integer: %d\n", *((int *) (array + 4)));
return 0;
}
On a big endian system you would first assign the most significant byte, and move on to the least significant bytes.
Replace
cArray[6] = (char) 0; // WHY DOES THIS NOT WORK???
printf("%c\n", cArray[5]);
By
cArray[6] = (char)51;
printf("%c\n", cArray[6]);
Should display '3'
I think you will understand your mistake... 0 as int does not represent the printable character '0', but the NULL termination string
51 as int represent the character '3'
You may use itoa(0,&cArry[6],10).
Use the correctly desired format specifier.
cArray[6] = (char) 0; does store an integer 0 into array element cArray[6]. Its the printf() that is fooling OP into thinking that did not work.
Using %c says OP wants the character that is encoded with a 0. (It usually not visible). Use %d to print the integer value of cArray[6].
printf("%d\n", cArray[6]);
You can add the ASCII value of 0 to the value you want to store digit into the character array.
For example if you want to store 0,1,...,9 into the character array A[10], you may use the following code.
for(j = 0; j<k; j++)
{
A[j] = j + '0'; // Same effect if you use A[j] = j + 0x30
}
This works only if the integer you want to store is less than 10. Otherwise you will have to extract the digits using modulo operator and store.

Simple int to char[] conversion

I have a simple question
How to simply convert integer (getting values 0-8) to char, e.g. char[2] in C?
Thanks
main()
{
int i = 247593;
char str[10];
sprintf(str, "%d", i);
// Now str contains the integer as characters
}
Hope it will be helpful to you.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
int a = 543210 ;
char arr[10] ="" ;
itoa(a,arr,10) ; // itoa() is a function of stdlib.h file that convert integer
// int to array itoa( integer, targated array, base u want to
//convert like decimal have 10
for( int i= 0 ; i < strlen(arr); i++) // strlen() function in string file thar return string length
printf("%c",arr[i]);
}
Use this. Beware of i's larger than 9, as these will require a char array with more than 2 elements to avoid a buffer overrun.
char c[2];
int i=1;
sprintf(c, "%d", i);
If you want to convert an int which is in the range 0-9 to a char, you may usually write something like this:
int x;
char c = '0' + x;
Now, if you want a character string, just add a terminating '\0' char:
char s[] = {'0' + x, '\0'};
Note that:
You must be sure that the int is in the 0-9 range, otherwise it will fail,
It works only if character codes for digits are consecutive. This is true in the vast majority of systems, that are ASCII-based, but this is not guaranteed to be true in all cases.
You can't truly do it in "standard" C, because the size of an int and of a char aren't fixed. Let's say you are using a compiler under Windows or Linux on an intel PC...
int i = 5;
char a = ((char*)&i)[0];
char b = ((char*)&i)[1];
Remember of endianness of your machine! And that int are "normally" 32 bits, so 4 chars!
But you probably meant "i want to stringify a number", so ignore this response :-)

Resources