I am not quite understanding the output of the following function - c

I wrote a simple sum() function in C with two arguments of integer type. But, while calling the function in main, I passed char type variables. The problem is I am not able to understand the output of the program. Following is the code.:
void sum(int x,int y)
{
printf(" x=%d y=%d\n",x,y);
printf("%d",x+y);
}
void main()
{
char a,b,add;
printf("Enter two values: ");
scanf("%c%c",&a,&b);
sum(a,b); //calling
}
If I input a=A and b=A then it should give me the addition of ASCII values of A, i.e. 130, but it is giving me 97.
When I try to print the value of x and y, it prints x=65 y=32. I don't understand why it stores 32 in y? Can someone please explain this.

This is because your input was A A, which is A<spacebar>A. The scanf("%c%c",&a,&b) read exactly two characters, A and <spacebar>, which resulted x = 65(A), y= 32(<spacebar>). If you want to get the intended output, your input should be AA.

It seems that you are giving input as A A instead of AA. For the former, x stores 65 and y stores 32 as the ASCII value of space is 32.

If you want to store 124abc in a integer variable then it will store only 124.
And in the definition of character constant/variable it can save all ASCII 255 character's which include also space(spacebar),tab(tab key),newline(enter key).
so when you run code and the screen show "Enter two values: ". You type 'A' which store in variable 'a'. Now you press space bar which is also a character constant which have value of ASCII 32 store into variable 'b'. so avoid this situation you should put a space before %c so it never read enter key or space bar.
Or use fflush(stdin) function.

Related

Why the second scanf also changes the variate presented in the first scanf?

I want to input an integer number and a character with scanf funtion, but it didn't work as I want.
The codes are as follows.
#include <stdio.h>
int main()
{
int a;
char c;
scanf("%d",&a);
scanf("%2c",&c);
printf("%d%c",a,c);
return 0;
}
I tried to input 12a (there is a space after a) from the terminal, but the output is not "12a" but "32a".
I also tried to run the code above step by step and found that when it run into the first "scanf", the value of "a" is 12, but when run into second "scanf", the value of "a" turned 32.
I want to figure out why the second scanf changes the value of a, which is not presented.
The problem is that the compiler has put variable a just behind variable c. When you do the second scanf() you specify to read two characters into a variable that has space only for one. You have incurred in a buffer overflow, and have overwritten memory past the variable c (and a happens to be there). The space has been written into a and this is the reason that you get 32 output (a has been stored the value of an ASCII SPACE, wich is 32).
What has happened is known as Undefined Behaviour, and it's common when you make this kind of mistakes. You can solve this by definning an array of char cells with at least two cells for reading the two characters . and then use something like:
#include <stdio.h>
int main()
{
int a;
char c[2];
scanf("%d", &a);
scanf("%2c", c); /* now c is a char array so don't use & */
printf("%d%.2s", a, c); /* use %.2s format instead */
return 0;
}
Note:
the use of %.2s format specifier is due to the fact that c is an array of two chars that has been filled completely (without allowing space to include a \0 string end delimiter) this would cause undefined behaviour if we don't ensure that the formatting will end at the second character (or before, in case a true \0 is found in the first or the second array positions)
Quoting C11, chapter 7.21.6.2, The fscanf function (emphasis mine)
c
[...]If an l length modifier is present, the input shall be a sequence of multibyte characters that begins in the initial shift state. Each multibyte character in the sequence is converted to a wide character as if by a call to the mbrtowc function, with the conversion state described by an mbstate_t object initialized to zero before the first multibyte character is converted. The corresponding argument shall be a pointer to the initial element of an array of wchar_t large enough to accept the resulting sequence of wide characters. [...]
and you're supplying a char *. The supplied argument does not match the expected type of argument, so this is undefined behavior.
Therefore the outcome cannot be justified.
To hold an input like "a ", you'll need a (long enough) char array, a char variable is not sufficient.

Can anyone explain me the output of this code?

char c[] = "hello";
printf("%*d", c);
the output is :
infinite loop of spaces
Can anyone explain me the output of this code?
infinite loop of spaces
char c[] = "hello";
printf("%*d", c);
the %*d say the first arg after the format indicates the width, here it is the address of c interpreted as a huge number, and the default added character to respect the width is a space.
note there is a missing arg normaly giving the value to print
if I use a valid code like that :
#include <stdio.h>
int main()
{
printf("%0*d\n", 3, 1);
return 0;
}
the result is 001 because I ask for to write '1' with a width of 3 and the added character is '0'
c is an array of char which holds hello but what is an array. it is a pointer with a chunk of memory mean above we create an array means we create a pointer whose point blocks of memory which hold hello string like c variable. it means c contain Adresse of the first block of hello.
now we look into printf("%*d")
printf("%*d") * represent the width and second parameter d represent a integer
u can see that how * symbol work in below example
printf("output is:%*c",3,c): its output:' h'
here is width three and print a char which hold c and that is h
now see why screen has infinite loop let's see printf("%'*'d",c)
we know the first argument is the width and second output is data here our first argument is c which is an array and u know array hold address of the first block
Code executed it give an address to width and u know the address is too long and it sometimes negative then why your screen has too much space not infinite because u give width as a long as a address further doubt comment me

issues with C Program to convert user input to Integer and then Integer to (HEX, Bin, Alpha)

#include <stdio.h>
#include <stdlib.h>
int main(void) {
/*holds the number to be converted between methods.*/
char convNumber;
/*storageInt */
int storageInt;
puts("put text in here to convert to bin");
while ((convNumber = getchar()) != '$') {
storageInt = storageInt * 100 + convNumber;
}
printf("%d", &storageInt);
return 0;
}
ok, Above is the code that is giving me problems. I'm new to C and this is a school project.
Question:
How do i convert user input with a delimiting character '$' into an integer which I can store and print or use to convert to hex or binary. At the bottom of the page is a full view of what my output should eventually look like to give an idea of the type of input required.
Background and assignment info:
I keep getting unexpected output when attempting to print the user input as an integer. My goal is to have blocks of 2 integers, representing ASCII, in order from 0 to N (N is the end of user input). User input is designated as finished by typing $. What am I doing wrong?
When going through the program choosing "A", "A", and then finally "A$" ($ for terminating the program) I get 2337412 instead of the expected 65 ascii for 'A'.
So please help me understand this so I will do better on subsequent assignments (looking for explanations). Thanks in advance!
END RESULT:
Welcome to the Coder!
Choose Input (H,A,B,Q): A
Choose Output(H,A,B): H
Enter your alpha input.
Hi! Bye! $
486921204279652120
Choose Input (H,A,B,Q): H
Choose Output(H,A,B): B
Enter your hex input.
486921204279652120$
010010000110100100100001001000000100001001111001011001010010000100100000
Choose Input (H,A,B,Q): B
Choose Output(H,A,B): A
Enter your bin input.
You are printing storageInt's memory address. You use memory addresses only in scanf for reasons you'll find obvious after you learn more. Strings are an exception, but this is not a string.
Do this:
printf("%d", storageInt);

incompatible types in assignment of `float' to `char[3]'

trying to figure out what is going on here. I'm just learning C, so go easy on me. :P I was assigned to create a unit converter from centimeters to inches. I've got it. Now I want to spice it up a little by creating options. My compiler isn't enjoying what I have. this is the first few lines....
main(void)
{
float centimeter;
char cnv[3];
float entry;
float oz;
float lb;
float cm;
float lb1;
centimeter=2.54;
lb1=2.2;
printf("Hello. Please type exactly, the type of conversion you would like to do.\n\n1. cm to in\n\n2. lb to kg\n");
scanf("%3c",&cnv);
if (strcmp(cnv=cm));
{
printf("Please enter your length in centimeters:\n");
scanf("%f",&entry);
printf("with %.0f centimeters in length, that converts to %.2f inches.",entry,entry/centimeter);
}
if (strcmp(cnv=lb));
{
printf("Please enter your weight in pounds:\n");
scanf("%f",&entry);
printf("with %.0f Pound(s) of weight, that converts to %.2f Kilogram(s).",entry,entry/lb1);
}
}
and it's giving me the error in the title. How can I fix this?
1) You're confusing = (assignment) with == (test for equality)
2) You can't compare a numeric value directly to a character array. You need to convert one or the other to a type which can be compared -- convert the number to string, if your using strcmp() (and understand how that function returns its results, which aren't what you've assumed here), or convert the string to a numeric type and compare that way.
The '=' operator is used for assigning values not comparison. You should use '==' for comparisons.
The values that you are of different types. You should convert one of the variables to the other type to compare.
Strings must be compared with some string comparison function like strcmp() as you have done, but strcmp() is a function and therefore the you should pass the parameters in with a comma separating them.
As an aside strcmp() returns 0 when the strings that you pass in are equivalent, so using a syntax more like this would be appropriate: if(!strcmp(cnv, cm)) or if(strcmp(cnv, cm) == 0)
If I might take a guess what you really were looking to do was something like: if(strcmp(cnv, "cm") == 0) cm is a name of a variable whereas "cm" is a zero terminated string with the characters 'c' and 'm'
The next thing that you will need to worry about is reading in the 3 characters from scanf, because if the input was "cm" and the user pressed enter to enter the text. The program scanned 3 characters one of which was the newline character '\n'. So when you go to do the strcmp() the program will compare each character up till it reaches a byte that has been zeroed out. With just 3 characters being read I am not sure if the string you are capturing is zero terminated, but I am sure that the string could contain a '\n' which would throw the results of strcmp() way off.
Thestrcmp syntax is not correct. For more about string compare function please check this link
http://www.tutorialspoint.com/ansi_c/c_strcmp.htm

New to C: whats wrong with my program?

I know my way around ruby pretty well and am teaching myself C starting with a few toy programs. This one is just to calculate the average of a string of numbers I enter as an argument.
#include <stdio.h>
#include <string.h>
main(int argc, char *argv[])
{
char *token;
int sum = 0;
int count = 0;
token = strtok(argv[1],",");
while (token != NULL)
{
count++;
sum += (int)*token;
token = strtok(NULL, ",");
}
printf("Avg: %d", sum/count);
printf("\n");
return 0;
}
The output is:
mike#sleepycat:~/projects/cee$ ./avg 1,1
Avg: 49
Which clearly needs some adjustment.
Any improvements and an explanation would be appreciated.
Look for sscanf or atoi as functions to convert from a string (array of characters) to an integer.
Unlike higher-level languages, C doesn't automatically convert between string and integral/real data types.
49 is the ASCII value of '1' char.
It should be helpful to you....:D
The problem is the character "1" is 49. You have to convert the character value to an integer and then average.
In C if you cast a char to an int you just get the ASCII value of it. So, you're averaging the ascii value of the character 1 twice, and getting what you'd expect.
You probably want to use atoi().
EDIT: Note that this is generally true of all typecasts in C. C doesn't reinterpret values for you, it trusts you to know what exists at a given location.
strtok(
Please, please do not use this. Even its own documentation says never to use it. I don't know how you, as a Ruby programmer, found out about its existence, but please forget about it.
(int)*token
This is not even close to doing what you want. There are two fundamental problems:
1) A char* does not "contain" text. It points at text. token is of type char*; therefore *token is of type char. That is, a single byte, not a string. Note that I said "byte", not "character", because the name char is actually wrong - an understandable oversight on the part of the language designers, because Unicode did not exist back then. Please understand that char is fundamentally a numeric type. There is no real text type in C! Interpreting a sequence of char values as text is just a convention.
2) Casting in C does not perform any kind of magical conversions.
What your code does is to grab the byte that token points at (after the strtok() call), and cast that numeric value to int. The byte that is rendered with the symbol 1 actually has a value of 49. Again, interpreting a sequence of bytes as text is just a convention, and thus interpreting a byte as a character is just a convention - specifically, here we are using the convention known as ASCII. When you hit the 1 key on your keyboard, and later hit enter to run the program, the chain of events set in motion by the command window actually passed a byte with the value 49 to your program. (In the same way, the comma has a value of 44.)
Both of the above problems are solved by using the proper tools to parse the input. Look up sscanf(). However, you don't even want to pass the input to your program this way, because you can't put any spaces in the input - each "word" on the command line will be passed as a separate entry in the argv[] array.
What you should do, in fact, is take advantage of that, by just expecting each entry in argv[] to represent one number. You can again use sscanf() to parse each entry, and it will be much easier.
Finally:
printf("Avg: %d", sum/count)
The quotient sum/count will not give you a decimal result. Dividing an integer by another integer yields an integer in C, discarding the remainder.
In this line: sum += (int)*token;
Casting a char to an int takes the ASCII value of the char. for 1, this value is 49.
Use the atoi function instead:
sum += atoi(token);
Note atoi is found in the stdlib.h file, so you'll need to #include it as well.
You can't convert a string to an integer via
sum += (int)*token;
Instead you have to call a function like atoi():
sum += atoi (token);
when you cast a char (which is what *token is) to int you get its ascii value in C - which is 49... so the average of the chars ascii values is in fact 49. you need to use atoi to get the value of the number represented

Resources