the code is like this:
char c;
scanf("%d", &c);
inputting 3...
My guess is that when 3 is inputted, it is as type int;
and then type-demoted to char and assigned to c;
I print the value of c in specifier %d yielding 3, seems to be as expected;
but printing the value of c with specifier %c yields --a blank-- on the terminal;this is one question...(1);
to test more I furthermore declare a variable ch with type char and initialized it like this:
char ch = 1;
and the test is like this:
(i&j)? printf("yes") : printf("no");
and the result is "no"
I print out the value of i&j, and it is 0
but 1&3 should be 1? this is another question....(2);
my question is (1) and (2)
You're actually invoking undefined behavior doing that.
By using the format string %d, you're telling scanf to expect an int* as a parameter and you're passing it a pointer to a single character. Remember that scanf has no further type information on what you're passing it than what you're putting in the format string.
This will result in scanf attempting to write an int sized value to memory at an address that points to a char sized reservation, potentially (and for most architectures) writing out of bounds.
After invoking UB, all bets are off on your further calculations.
Suppose that scanf() were not a varargs-function, but a plain ordinary function taking a pointer-to-int as the 2nd argument:
int noscanf(char *format, int *ptr)
{
*ptr = 42;
return 1;
}
int main(void)
{
char ch;
int rc;
// This should *at least* give a warning ...
rc = noscanf("Haha!" , &ch);
return 0;
}
Now, scanf() is a varargs function. The only way for scanf() to determine the type of the (pointer) arguments is by inspecting the format string. And a %d means : the next argument is supposed to be a pointer to int. So scanf can happily write sizeof(int) bytes to *ptr.
I can't see a variable jthere. So i&j will be 0. And yes, if i == 1 and j == 3 then i & j == 1.
(i&j)? printf("yes") : printf("no");
statement gives the output yes,for i=1 and j=3.
And for (1) question ASCII 3 is for STX char which is not printable.
Related
int getLevelWidth(FILE *level){
char a;
int i = 0;
while(fgets(&a, 2, level)) {
printf("%c",a);
i++;
}
printf("%i", i);
return 0;
}
This is file's content:
ABCDEFGHIJ
KLMNOPQ
RSTUVW
XYZ
And this is the output:
ABCDEFGHIJ
KLMNOPQ
RSTUVW
XYZ
1
The fgets function expects as its first parameter a pointer to the first element of an array of char, and the length of that array as the second. You're passing it the address of a single character and telling it that it is an array of size 2. This means that fgets is writing past the bounds of the variable c, triggering undefined behavior.
What most likely happened in this particular case is that a was followed immediately by i in memory, so writing past the bounds of a ended up writing into i. And assuming your system uses little-endian byte ordering, the first byte of i contains its lowest order byte. So by treating a as a 2 character array, the character in the file is written into a and the terminating null byte (i.e. the value 0) for the string is written into the first byte of i, and assuming the value of i was less than 256 this resets its value to 0.
But again, this is undefined behavior. Just because this is what happened in this particular case doesn't mean that it will always happen.
Since you only want to read a single character at a time, you instead want to use fgetc. You'll also want to change the type of c to an int to match what the function returns so you can check for EOF.
int a;
int i = 0;
while((a=fgetc(level)) != EOF) {
printf("%c",a);
i++;
}
You need 2 chars long buffer. Your code is writing 2 chars into single char. So the second one is written out of bounds. It is undefined behaviour.
Using same fgets function:
int getLevelWidth(FILE *level){
char a[2];
int i = 0;
while(fgets(a, 2, level)) {
printf("%c",a[0]);
i++;
}
printf("%i", i);
return 0;
}
I am trying to write code for reverse polish notation calculator. Why when I input a number the following code gets executed twice ?
int a[50];
int topOfStack = -1;
char c;
while((c = getchar()) != EOF)
{
int n = atoi(&c);
topOfStack += 1;
a[topOfStack] = n;
printf("top of stack is %d\n", a[topOfStack]);
printf("index top of stack is %d\n", topOfStack);
}
return 0;
}
This
int n = atoi(&c);
is undefined behavior.
The atoi() function takes a char * pointer pointing to a string, AKA a sequence of non-nul bytes followed by a nul byte.
You are passing a pointer to a single char, then atoi() increments the pointer trying to find the terminating '\0' but dereferencing the incremented pointer is undefined behavior because the pointer does not point to an array.
When there is undefined behavior in your code, it doesn't matter what other behavior you observe because it might very well be caused by the undefined behavior problem.
To convert a single char to int you just need to subtract the ascii value of 0 from the ascii value of the digit like this
int n = c - '0';
but that doesn't guarantee that n is the value you expect, for that you need to check with isdigit(c) before attempting to use c as if it were a digit.
Also: The type of c is wrong, it should be int since getchar() returns int and you don't want the value to be truncated.
I want to write something like the following code, but I failed.
I want to assign dynamic number of chars from array y to x. This number will be defined later. Here is a simple example of what I mean.
#include<stdio.h>
int main()
{
int x=0;
char y[]={'5','4'};
int z=1;
sscanf(y,"%zi",&x);
printf("%i",x); //Each time value of x=0
sscanf(y,"%1i",&x); //I want to make this 1 dynamic "int z"
printf("%i",x); //Here x value =54.
return 0;
}
Succinctly, you can't do what you want directly.
With printf(), you can use this, where all three variables are of type int and the widths will be read from x and y:
printf("%*.*d", x, y, z);
However, the scanf() family of functions provides nothing analogous. A * means 'assignment suppression' in scanf(). Note that in C99 and beyond, %zi tells scanf() that the type of the pointer argument is size_t *. This probably accounts for why you got 0 as a result; sscanf() was writing out of bounds for the variable you passed to it.
Your best bet is to use snprintf() to create the format string you want used by scanf().
int x;
char y[] = { '5', '4' };
int z = 1;
char format[16];
snprintf(format, sizeof(format), "%%%di", z);
if (sscanf(y, format, &x) != 1)
…handle error…
printf("%d\n", x); // Will print 5
Note that if z is 1 or 2, this works OK; if z is larger, then y is not a null-terminated string and you run into undefined behaviour. If z is zero or negative, you run into problems too.
If you see , you declared and initialized array like this -
char y[]={'5','4'};
y is not a string because it is not terminated using '\0' , so you need to explicitly add nul terminater . As sscanf will take a c-style string as first argument.
char y[]={'5','4','\0'}; // or char y[]="54";
Working demo
I have a problem, %n in printf doesn't work, i'm using Dev-Cpp 5.3.0.4 on win7
#include<stdio.h>
int main(void)
{
int n;
char *x;
gets(x);
printf("\n%s%n\n",x,&n);
printf("n: %d\n",n);
return 0;
}
output:
hello how are you?
hello how are you?n: 2046
--------------------------------
Process exited with return value 0
Press any key to continue . . .
why? how can i solve? thanks in advance ;)
Have a look at the printf manpage:
n The number of characters written so far is stored into the integer indicated by the int
* (or variant) pointer argument. No argument is converted.
So, you'll have to pass a pointer to an int. Also, as Xavier Holt pointed out, you'll have to use a valid buffer to read into. Try this:
#include <stdio.h>
int main(void)
{
int n;
char x[1000];
fgets(x, 1000, stdin);
printf("\n%s%n\n",x,&n);
printf("n: %d\n",n);
return 0;
}
This code works for me.
You need to pass a pointer to n.
The argument to n needs to be a pointer to a signed int, not a singed int.
That's not how to use the "%n" specifier.
See the C99 Standard.
n
The argument shall be a pointer to signed integer into which is written the number of characters written to the output stream so far by this call to fprintf. No argument is converted, but one is consumed. If the conversion specification includes any flags, a field width, or a precision, the behavior is undefined.
Also you need some place to store the input (hint: initialize x)
Hello im just beginning to learn C and i want to know why im getting a problem here..
i wish to pass a char pointer
char *temp;
into a function ie call to function
checkIfUniqueCourseNo(temp,k);
with a prototype
int checkIfUniqueCourseNo(char checkchar[4],int);
and a function header
int checkIfUniqueCourseNo(char checkchar[4], int k)
Im sure im doing something really stupid here but im not sure how to fix it :(
thanks in advance. ps my error is that checkchar[4] outputs a P...
Example---
temp = "123A"
checkIfUniqueCourseNo(temp,k);
int checkIfUniqueCourseNo(char checkchar[4], int k){
printf("CheckifUniqueCourse\n");
printf("Check Value = %c \n", checkchar);
return 0;
}
Output = Check Value = P
temp = "123A"
checkIfUniqueCourseNo(temp,k);
int checkIfUniqueCourseNo(char checkchar[4], int k){
printf("CheckifUniqueCourse\n");
printf("Check Value = %c \n", checkchar);
^^^^^^^^^
return 0;
}
If you're trying to print out the first character of checkchar, then you need to change this line to either
printf("Check Value = %c\n", *checkchar);
or
printf("Check Value = %c\n", checkchar[0]);
In the context of a function parameter declaration, T a[N] and T a[] are equivalent to T *a; a is declared as a pointer to T, not an array of T.
When you wrote
printf("Check Value = %c\n", checkchar);
you lied to printf; you said the argument is supposed to be of type char, but you passed a char *. Hence the bogus output.
If you want to print out the entire string "1234", then you need to change that line to
printf("Check value = %s\n", checkchar);
This time we use the %s conversion specifier to tell printf that checkchar points to a 0-terminated array of char (a.k.a. a string).
This is not at all clear. Are you assigning any value to temp? If so, what?
It would make more sense to have your prototype as:
int checkIfUniqueCourseNo(char* checkchar, int);
Since it's not at all clear where you got the 4 from.
It's been a while since I've done C, but I can see a few problems here, temp = "123A" actually requires an array for 5 characters (one of which is to include the '\0' string terminating character).
Secondly, the line printf("Check Value = %c \n", checkchar); seems to be trying to print a memory pointer as a character, change it to the following: printf("Check Value = %s \n", checkchar); and it will output each character in the array until it hits the terminating character.
There are a couple of things to look at here, you need to take a good look at the data you have, how it is represented and what you want to do with it.
Your course code appears to be a four character string, you should know that traditionally, strings in C also include an extra byte at the end with the value of zero (NUL) so that the many string functions that exist know that they have reached the end of the string.
In your case, your four digit code takes up five bytes of memory. So wont fit well passing it into your function.
If I were you, I would pass in a pointer like so:-
int checkIfUniqueCourseNo(char* coursecode, int k ) {
int rv = -1;
if ( coursecode == NULL ) return rv;
//...
I have no idea what K is for, do you?
Once you have your sequence of bytes inside your function you can save yourself alot of hastle later by doing some simple bounds checking on the data like so:
//...
if ( strlen(coursecode) > 4 ){
fprintf(stderr,"course code too long\n");
return rv;
}
if ( strlen(coursecode) < 4 ){
fprintf(stderr,"course code too short\n");
return rv;
}
//...
You can be sure you have a 4 character string now..