I'm trying to add an int to a char array. My (broken) code is as follows,
string[i] = (char) number;
with i being some int index of the array and number is some integer number. Actually, while typing this out I noticed another problem that would occur if the number is more than one digit, so if you have some answer to that problem as well that would be fantastic!
Given the revised requirement to get digit '0' into string[i] if number == 0, and similarly for values of number between 1 and 9, then you need to add '0' to the number:
assert(number >= 0 && number <= 9);
string[i] = number + '0';
The converse transform is used to convert a digit character back to the corresponding number:
assert(isdigit(c));
int value = c - '0';
If you want to convert a single digit to a number character you can use
string[i] = (char) (number+'0');
Of course you should check if the int value is between 0 and 9. If you have arbitrary numbers and you want to convert them to a string, you should use snprintf, but of course, then you can't squeeze it in a char aynmore, because each char represents a single digit.
If you create the digit representation by doing it manually, you should not forget that a C string requires a \0 byte at the end.
You'll want to use sprintf().
sprintf(string,'%d',number);
I believe.
EDIT: to answer the second part of your question, you're casting an integer to a character, which only holds one digit, as it were. You'd want to put it in a char* or an array of chars.
use asprintf :
char *x;
int size = asprintf(&x, "%d", number);
free(x);
is better because you don't have to allocate memory. is done by asprintf
Related
I am new to C programming and trying to make a program to add up the digits from the input like this:
input = 12345 <= 5 digit
output = 15 <= add up digit
I try to convert the char index to int but it dosent seems to work! Can anyone help?
Here's my code:
#include <stdio.h>
#include <string.h>
int main(){
char nilai[5];
int j,length,nilai_asli=0,i;
printf("nilai: ");
scanf("%s",&nilai);
length = strlen(nilai);
for(i=0; i<length; i++){
int nilai1 = nilai[i];
printf("%d",nilai1);
}
}
Output:
nilai: 12345
4950515253
You have two problems with the code you show.
First lets talk about the problem you ask about... You display the encoded character value. All characters in C are encoded in one way or another. The most common encoding scheme is called ASCII where the digits are encoded with '0' starting at 48 up to '9' at 57.
Using this knowledge it should be quite easy to figure out a way to convert a digit character to the integer value of the digit: Subtract the character '0'. As in
int nilai1 = nilai[i] - '0'; // "Convert" digit character to its integer value
Now for the second problem: Strings in C are really called null-terminated byte strings. That null-terminated bit is quite important, and all strings functions (like strlen) will look for that to know when the string ends.
When you input five character for the scanf call, the scanf function will write the null-terminator on the sixth position in the five-element array. That is out of bounds and leads to undefined behavior.
You can solve this by either making the array longer, or by telling scanf not to write more characters into the array than it can actually fit:
scanf("%4s", nilai); // Read at most four characters
// which will fit with the terminator in a five-element array
First of all, your buffer isn't big enough. String input is null-terminated, so if you want to read in your output 12345 of 5 numbers, you need a buffer of at least 6 chars:
char nilai[6];
And if your input is bigger than 5 chars, then your buffer has to be bigger, too.
But the problem with adding up the digits is that you're not actually adding up anything. You're just assigning to int nilai1 over and over and discarding the result. Instead, put int nilai1 before the loop and increase it in the loop. Also, to convert from a char to the int it represents, subtract '0'. All in all this part should look like this:
int nilai1 = 0;
for (i = 0; i < length; i++) {
nilai1 += nilai[i] - '0';
}
printf("%d\n", nilai1);
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
This character array
char nilai[5];
can not contain a string with 5 digits. Declare the array with at least one more character to store the terminating zero of a string.
char nilai[6];
In the call of scanf
scanf("%s",&nilai);
remove the operator & before the name nilai. And such a call is unsafe. You could use for example the standard function fgets.
This call
length = strlen(nilai);
is redundant and moreover the variable length should be declared having the type size_t.
This loop
for(i=0; i<length; i++){
int nilai1 = nilai[i];
printf("%d",nilai1);
}
entirely does not make sense.
The program can look the following way
#include <stdio.h>
#include <ctype.h>
int main(void)
{
enum { N = 6 };
char nilai[N];
printf( "nilai: ");
fgets( nilai, sizeof( nilai ), stdin );
int nilai1 = 0;
for ( const char *p = nilai; *p != '\0'; ++p )
{
if ( isdigit( ( unsigned char ) *p ) ) nilai1 += *p - '0';
}
printf( "%d\n", nilai1 );
return 0;
}
Its output might look like
nilai: 12345
15
int k=5;
char* result = (char *)malloc(100 * sizeof(char));
result[count] = k;
Considering the above code, if I print the contents of result[count] it prints smiley symbols. I tried like below,but of no use.
result[count]=(char)k;
Can anyone help me?
I am percepting that malloc(100*sizeof(char)) will create 100 blocks each of size of character contiguously. Please correct me if I am wrong?
I'll disregard all the fluff about arrays and malloc as it is irrelevant to the problem you describe. You seem to essentially be asking "What will this code print:"
char c = 5;
printf("%c", c);
It will print the symbol 5 in your symbol table, most likely a non-printable character. When encountering non-printable characters, some implementations choose to print non-standard symbols, such as smileys.
If you want to print the number 5, you have to use a character literal:
char c = '5';
printf("%c", c);
or alternatively use poor style with "magic numbers":
char c = 53; // don't write code like this
printf("%c", c);
It is a problem of character representation. Let's begin by the opposite first. A char can be promoted to an int, but if you do you get the representation of the character (its code). Assuming you use ASCII:
char c = '5';
int i = c; // i is now 0x35 or 53 ASCII code for '5'
Your example is the opposite, 5 can be represented by a char, so result[count] = k is defined (even if you should have got a warning for possible truncation), but ASCII char for code 5 is control code ENQ and will be printed as ♣ on a windows system using code page 850 or 437.
A half portable (not specified, but is known to work on all common architectures) way to do the conversion (int) 5 -> (char) '5' is to remember that code '0' to '9' are consecutive (as are 'A' to 'Z' and 'a to 'z'), so I think that what you want is:
result[count] = '0' + k;
First, let's clean up your code a bit:
int k=5;
char* result = malloc(100);
result[count] = k;
sizeof(char) is always equal to 1 under any platform and you don't need to cast the return of malloc() in C.
This said, as long as your count variable contains a value between 0 and 99, you're not doing anything wrong. If you want to print the actual character '5', then you have to assign the ASCII value of that character (53), not just the number 5. Also, remember that if that array of chars has to be interpreted as a string, you need to terminate it with '\0':
int k=5, i;
char* result = malloc(100);
for (i=0; i<98; i++) {
result[i] = ' ';
}
result[98] = 53;
result[99] = '\0';
printf("%s\n", result);
The elements in the array you're trying to allocate are all the size of a char, 1 byte. An int is 4 bytes thus your issues. If you want to store ints in an array you could do:
int result[100];
Followed by storing the value, but honestly from the way your questioned is posed I don't know if that's actually what you're trying to do. Try rephrasing the post with what you're trying to accomplish.
Are you trying to store 5 as a character?
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.
It is a very trivial question but I don't know why I am not getting the correct output. Here is what I am trying to do:
char sendBuffer[1000];
int count=0:
while(count<10)
{
sendBuffer[0]=count;
sendBuffer[1]='a';
sendBuffer[2]='b';
sendBuffer[3]='c';
sendBuffer[4]='\0';
printf(%s,sendBuffer);
count=count+1;
}
In the output, all buffer is printed correctly except the first index. I want 1,2,3 and so on to be printed at the start of the buffer but it does not work. Please Help
You need to convert that number into a character. A cheap way to do it is:
sendBuffer[0] = '0' + count;
is there anyway to display integers greater than 9
If you need that you'll want to shift to more elaborate schemes. For example, if you want to convert an integer 42 into the string "42" you can say:
#define ENOUGH ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)
char str[ENOUGH];
snprint(str, sizeof str, "%d", 42);
Credit for ENOUGH goes to caf.
printf(%s,sendBuffer); should be printf("%s",sendBuffer);
Change
sendBuffer[0]=count;
to
sendBuffer[0]='0' + count;
i.e. convert the integer 0...9 to the characters '0' ... '9'
Also add a quote i.e. printf("%s",sendBuffer);
Quoted from the question:
In the output, all buffer is printed correctly except the first
index.i want 1,2,3 and so on to be printed at the start of the buffer
but it does not work. Please Help
I think her problem is that she does not get any output for the first line. That is because in the first iteration, count is 0, i.e. sendBuffer[0] is 0 which is the '\0' character. Hence the string is treated as empty.
You are trying to print the ascii characters corresponding to decimal values 0-9 which are non-printable characters. If you need to print decimal 0-9 then initialise count to 48 which is the ascii decimal code for '0' and change the condition in the while block to count < 58; 57 is the ascii deciaml code for '9'. See below:
char sendBuffer[1000];
int count=48:
while(count<58)
{
sendBuffer[0]=count;
sendBuffer[1]='a';
sendBuffer[2]='b';
sendBuffer[3]='c';
sendBuffer[4]='\0';
printf(%s,sendBuffer);
count=count+1;
}
To convert an integer value to a char representation, add the value of the character '0':
sendBuffer[0]=count + '0';
Notice that's the character '0', not the number 0. This is because of how ascii values work. The char with a literal value of 0 is \0, the null terminator. Digit '0' has a literal value of 48, '1' 49 and so on.
This works for the digits 0-9. You can't put a char representation of a number bigger than that in a single char, obviously.
char sendBuffer[1000];
// take fixed stuff outside the loop
sendBuffer[1]='a';
sendBuffer[2]='b';
sendBuffer[3]='c';
sendBuffer[4]='\0';
// it's best not to rely on order of ASCII values
for(char* numbers="0123456789"; *numbers!=0; numbers++){// use for loop for numbers
sendBuffer[0] = *numbers;
printf("%s",sendBuffer);
}
I'm trying to convert the digit's 0 to 9 to ASCII using _itoa_s and I find myself running into stack corruption errors using MSVC2012.
I thought that the ASCII table only occupied one byte per character, but from the looks of things, one byte isn't enough.
Where is my thinking wrong?
for (int digit = 0; digit < 10; digit++)
{
char ch_digit;
_itoa_s(digit, &ch_digit, 1, 10);
}
I thought this simple loop should succeed, however it fails. I'm baffled.
_itoa_s() should write out one char AND the terminating NUL char. You want it to write into a buffer with length = 1. So either you get the corruption error because of uninitialized ch_digit, or _itoa_s() is not _s (secure) and shmashes your stack by writing behind that one char.
But why not just calculating the ASCII char for base 10 'by hand' instead of using this non portable, MS specific lumber ?
for (int digit = 0; digit < 10; digit++)
{
char ch_digit = '0' + digit; //'0' == 48 == 0x30
}
itoa_* writes a string, so there's a null-terminator involved.