I want to make a program which converts 3www2as3com0 to www.as.com but I have got trouble at the beginning; I want to convert the first number of the string (the character 3) to an integer to use functions like strncpy or strchr so when I print the int converted the program shows 51 instead of 3. What is the problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv) {
/* argv[1]--->3www2as3com0*/
char *string;
char *p;
string=argv[1];
p=string;
char cond,cond2;
cond=*p; //I want to have in cond the number 3
cond2=(int)cond; //I want to convert cond (a char) to cond2(an int)
printf("%d",cond2); //It print me 51 instead of 3
return (EXIT_SUCCESS);
}
Your computer evidently encodes strings in a scheme called ASCII . (I am fairly sure most modern computers use ASCII or a superset such as UTF-8 for char* strings).
Notice how both printable and nonprintable characters are encoded as numbers. 51 is the number for the character '3'.
One of the nice features of ASCII is that all the digits have increasing codes starting from '0'.
This allows one to get the numerical value of a digit by calculating aDigitCharacter - '0'.
For example: cond2 = cond - '0';
EDIT:
You should also probably also double check that the character is indeed a digit by making sure it lies between '0' and '9';
If you want to convert a string containing more than one digit to a number you might want to use atoi.
It can be found in <stdlib.h>.
The character's integer value is the ASCII code for the digit, not the number it actually represents. You can convert by subtracting '0'.
if( c >= '0' && c <= '9' ) val = c - '0';
Seems like the strings you are using will never have negative number, so you can use atoi(), returns the integer value from char. If it encounters something that is not a number, it will get the number that builds up until then.
Related
I was trying to make this int to char program. The +'0' in the do while loop wont convert the int value to ascii, whereas, +'0' in main is converting. I have tried many statements, but it won't work in convert() .
#include<stdio.h>
#include<string.h>
void convert(int input,char s[]);
void reverse(char s[]);
int main()
{
int input;
char string[5];
//prcharf("enter int\n");
printf("enter int\n");
scanf("%d",&input);
convert(input,string);
printf("Converted Input is : %s\n",string);
int i=54;
printf("%c\n",(i+'0')); //This give ascii char value of int
printf("out\n");
}
void convert(int input,char s[])
{
int sign,i=0;
char d;
if((sign=input)<0)
input=-input;
do
{
s[i++]='0'+input%10;//but this gives int only
} while((input/=10)>0);
if(sign<0)
s[i++]='-';
s[i]=EOF;
reverse(s);
}
void reverse(char s[])
{
int i,j;
char temp;
for(i=0,j=strlen(s)-1;i<j;i++,j--)
{
temp=s[i];
s[i]=s[j];
s[j]=temp;
}
}
Output screenshot
Code screenshot
The +'0' in the do while loop wont convert the int value to ascii
Your own screenshot shows otherwise (assuming an ASCII-based terminal).
Your code printed 56, so it printed the bytes 0x35 and 0x36, so string[0] and string[1] contain 0x35 and 0x36 respectively, and 0x35 and 0x36 are the ASCII encodings of 5 and 6 respectively.
You can also verify this by printing the elements of string individually.
for (int i=0; string[i]; ++i)
printf("%02X ", string[i]);
printf("\n");
I tried your program and it is working for the most part. I get some goofy output because of this line:
s[i]=EOF;
EOF is a negative integer macro that represents "End Of File." Its actual value is implementation defined. It appears what you actually want is a null terminator:
s[i]='\0';
That will remove any goofy characters in the output.
I would also make that string in main a little bigger. No reason we couldn't use something like
char string[12];
I would use a bare minimum of 12 which will cover you to a 32 bit INT_MAX with sign.
EDIT
It appears (based on all the comments) you may be actually trying to make a program that simply outputs characters using numeric ascii values. What the convert function actually does is converts an integer to a string representation of that integer. For example:
int num = 123; /* Integer input */
char str_num[12] = "123"; /* char array output */
convert is basically a manual implementation of itoa.
If you are trying to simply output characters given ascii codes, this is a much simpler program. First, you should understand that this code here is a mis-interpretation of what convert was trying to do:
int i=54;
printf("%c\n",(i+'0'));
The point of adding '0' previously, was to convert single digit integers to their ascii code version. For reference, use this: asciitable. For example if you wanted to convert the integer 4 to a character '4', you would add 4 to '0' which is ascii code 48 to get 52. 52 being the ascii code for the character '4'. To print out the character that is represented by ascii code, the solution is much more straightforward. As others have stated in the comments, char is a essentially a numeric type already. This will give you the desired behavior:
int i = 102 /* The actual ascii value of 'f' */
printf("%c\n", i);
That will work, but to be safe that should be cast to type char. Whether or not this is redundant may be implementation defined. I do believe that sending incorrect types to printf is undefined behavior whether it works in this case or not. Safe version:
printf("%c\n", (char) i);
So you can write the entire program in main since there is no need for the convert function:
int main()
{
/* Make initialization a habit */
int input = 0;
/* Loop through until we get a value between 0-127 */
do {
printf("enter int\n");
scanf("%d",&input);
} while (input < 0 || input > 127);
printf("Converted Input is : %c\n", (char)input);
}
We don't want anything outside of 0-127. char has a range of 256 bits (AKA a byte!) and spans from -127 to 127. If you wanted literal interpretation of higher characters, you could use unsigned char (0-255). This is undesirable on the linux terminal which is likely expecting UTF-8 characters. Values above 127 will be represent portions of multi-byte characters. If you wanted to support this, you will need a char[] and the code will become a lot more complex.
#include <stdio.h>
int main(int argc, const char * argv[]) {
unsigned char ch,i,letters[95];
int tapped [0];
ch=32; //start with 32 (space)
while(ch<=127){
ch++;
letters[i]=ch;
i++;
}
printf(letters);
return 0;
}
I'm trying to get the ASCII characters from 32 to 127 into an array so I can generate N random ones in another loop.
The issue is that I'm getting back all of them, but I'm also getting back some additional unexpected at the end:
!"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\200\300\367\277_\377
I don't understand why I'm getting \200\300\367\277_\377 at the end, since they aren't in the range. I'm new to C so is there some aspects of arrays that I'm not doing properly?
First, if you count the characters from 32 to 127, there are 96 of them. So letters should be defined with letters[96], not letters[95].
Second, you should not pass letters to printf as the first parameter. The first parameter should be a format string, not a string to be printed literally. In particular, since letters contains a “%” character, it is not a proper format string.
Third, when printing a string, printf expects a null-terminated string by default. To print an array of char that is not null-terminated, you can use a precision in the conversions specifier:
printf("%.96s\n", letters);
Fourth, you say you want all the characters from 32 to 127, but your loop starts with ch set to 32 and increments it before putting it into the array, so the first value put into the array is 33. You should nove the increment to later.
Fifth, you do not initialize i. It must be set to zero before starting the loop.
I am using the following code. I expect the output to be "Yes", but I instead get "No." I must be missing something very simple and fundamental.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int n = 3;
if (isdigit(n))
{
printf("Yes\n");
}
else
{
printf("No\n");
}
return 0;
}
isdigit checks whether the character passed to it is a numeric character. Therefore, its argument should be char type or int type which is the code of a character.
Here, you are passing 3 to isdigit. In ASCII, 3 is the code of the character ETX (end of text) which is a non-numeric character. Therefore, isdigit(3) returns false.
isdigit() expects a character code, while you expect it to accept a plain number.
Those expectations do not mesh well.
Character literals:
'0' ordinal 0x30 -- 48
'1' ordinal 0x31 -- 49
'2' ordinal 0x32 -- 50
... You get the drift
'3' is not a digit, here, in the way isdigit() considers them. Change int n = 3 to int n = '3'. If your system uses ASCII, for instance, 3 is the end of text marker, whereas 51, equivalent to '3', is the actual character three.
isdigit expects a character. If the character passed is digit then it returns non zero. 3 is an ASCII value of non-printable character, i.e it doesn't represent a digit and that's why your else body gets executed.
man isdigit:
These functions check whether c, which must have the value of an
unsigned char or EOF, falls into a certain character class according to
the current locale.
3 is an integer, not a character. In fact, 3 is also the value of a character that is not a digit.
The string "\03\t\nABCabc123" is composed of 12 characters. The first 9 characters all return false when applied to the isdigit() function. The last 3 all return true;
#include <ctype.h>
#include <stdio.h>
int main(void) {
char data[] = "\03\t\nABCabc123";
// data[0] = 3;
char *ptr = data;
while (*ptr) {
printf("%4d --> %s\n", *ptr, isdigit((unsigned char)*ptr) ? "true" : "false");
ptr++;
}
return 0;
}
Here is the implementation of function isdigit:
int isdigit(char c)
{
return '0' <= c && c <= '9';
}
In simple words, function isdigit takes a char argument as input:
If the input represents a decimal digit in ASCII format, then the function returns 1.
If the input does not represent a decimal digit in ASCII format, then the function returns 0.
When you call function isdigit with an int argument, the argument is first truncated to a char. That doesn't make any difference in your example, since 3 fits into a char, so no information is lost due to the truncation. However, since 3 does not represent any decimal digit in ASCII format, the return-value of isdigit(3) is 0.
To summarize the above:
The return-value of isdigit('0') is 1.
The return-value of isdigit('1') is 1.
...
The return-value of isdigit('9') is 1.
In all other cases, the-return value of isdigit(...) is 0.
Your mistake probably stems from the assumption that '3' == 3. If you want to check whether or not an int variable stores a single-decimal-digit value, then you can implement a slightly different function:
int isintdigit(int i)
{
return 0 <= i && i <= 9;
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{ char* key="844607587";
while(*key!=0){
printf("hello world,%c\n",*key);
key++;}
}
Why doesn't the program stop at the zero digit? Then what does the 0 mean? the one without ' '
You made a simple mistake - you are comparing the (most likely ASCII) characters in your string with the numeric value 0. Change:
while(*key!=0){
to
while(*key!='0'){
Note that The numeric value 0 is the value of the C string terminator, often written as '\0', so your code stops when it reaches the end of the string, rather than when it sees the character '0'.
while(*key!=0) should be while(*key!='0') to skip zero. key is string so *key will be char and you are trying to compare *key with integer zero not character zero.
I think because you're comparing each character to the number 0, which is not the same as the character '0'.
The character '0' is different from the numeric value 0. In ASCII '0' == 32
If key = "8446\07587" then while(*key!=0) will work fine, but since you're dealing with characters you'll need to compare characters instead
while (*key != '0')
You're comparing key to the 0 char or (null) character, instead of the 48 or the 0 character, try ''
while(*key!='0')
Or
while(*key!=48)
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);
}