I can't seem to find an answer as to why I am not able to type cast a counting integer into a char type within a for loop. Below is a simple instance in which I have tried to declare the type case before and after the loop begins but have not gotten any where. Fundamentally, I don't understand why this is not allowed and can't, or am too stupid to find any information on this.
#include <stdio.h>
int
main(void){
int i;
//char j; <-If i declare here
//char j=(char)i; <-or here there is no profound affect
for(i=0;i<9;++i){
char j=(char)i;
printf("i=%d, j=%c\n", i, j);} <--Case A: j=%c, Case B: j=%d
return 0;
}
OUTPUT
Case A Output printf("%c",j) (j initialized as char & typecast as char)
i=0, j=
i=1, j=
i=2, j=
i=3, j=
i=4, j=
i=5, j=
i=6, j=
i=7, j=
i=8, j=
Case B Output printf("%d",j) (j initialized as char & typecast as char)
i=0, j=0
i=1, j=1 <- if typecast from int to char worked these values should not
i=2, j=2 <- show up when using printf("%d",j)
i=3, j=3
i=4, j=4
i=5, j=5
i=6, j=6
i=7, j=7
i=8, j=8
I was expecting a printed value of the the number as a char instead of blank values. There could be an issue with terminal or ascii values not being represented properly, but that does not answer the root of my question. ** Case B shows numeric values for the j column. However, these values were printed as using a double place holder. If my type case from double to char had worked, these values would be either the associated ascii values for the numbers or garbage.** I'm not looking for a way around this, just to understand what is going on when the code is compiled or in runtime. Thanks!
The Terminal has maybe a problem with the NUL character when displayed with %c in the formated string. I changed the Program a bit..
#include <stdio.h>
int main(void){
int i, x=123456789;
//char j;
char j=(char)i;
printf("int i: %d\n",i);
printf("int x: %d\n",x);
printf("char j: %d\n",j);
printf("hex j: 0x%02x\n",j);
for(i=32;i<128;++i){
char j=(char)i;
printf("i=%d, j=0x%02x, j= %d, j =%c\n", i, j, j, j);
}
printf("char j: %c\n",j);
// Problems is the output as char?
// Programmers Notepad Consol Specific!
printf("Terminal Stops before this in PN :D\n");
return 0;
}
I think the Program does what you want when printing with %d or %x. But %c makes problems.
I used Programmers Notepad. Other Programs may not have my problem :D
Importand is that Printable characters start at decimal 32 with space. See ASCII Printable. Before that it is normal to get no output. %c tries to convert the decimal value in a printable character according to the ASCII table. Also have a look on the C reference.The %d is for signed decimal Integer.
Because the number you are trying to convert is bigger than a char. Char can only be 1 character, hence you can't fit 9 digits/characters into a single char. This would need to be a char[]/string to do what you are trying.
Or try changing x=0->9 but not more than a single digit.
Related
I am writing a code to take input from the user, and print it out exactly as it was input, through arrays.
void getArrays(char a[10][10], int b[10], int n ){
printf("Enter number of students and then those students names and scores separated by a space.\n");
scanf("%d", &n);
int i = 0;
while(i < n){
scanf("%s%d", a[i],&b[i]);
i++;
}
}
void printArrays(char a[10][10], int b[10], int n ){
int j;
for(j=0; j<n-1; j++){
printf("%s %d\n", a[j],b[j] );
}
}
In this scenario a is a character array that is 10 rows by 10 columns, while b is an array of ints, sized 10 rows as well. n is a number entered by the user before the arrays are created, specifying the amount of strings to be in the arrays.
The input would look something like this:
5
Jimmy 90
Tony 80
Troy 67
Dona 78
Dylan 97
At this point it cuts off, and prints the arrays, which worked properly. However, after the names were done printing, the terminal spit a multitude of numbers and random strings before giving me this error:
Segmentation Fault (core dumped)
I ran it through the gbd debugger, and was given the following message:
Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:65
65 ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
I've searched this error on the site, but the questions already asked didn't relate to my issue;
Weird Segmentation Fault after printing
Segmentation fault core dump
These are just two of the ones I've seen, and they were not the answer I was looking for.
I saw from further searches that it could be a pointer error, or a size discrepancy in the code when referring to an array. I narrowed the problem down to only occurring after it finished printing out the names. So I tried to change for(j=0; j<n; j++) to for(j=0; j<n-1; j++), and once again it gave me the same issues.
I think perhaps the for loop is reading past the number of elements I want it to, ie- instead of stopping at 3, (if n = 3), and it has nothing else to print so it gives me the segmentation fault error?
Do I need to use a pointer with n in this case, such as &n, or is the issue going to be with the size of my array?
The code that calls these functions is as follows:
int main(){
char names[10][15]; // can handle up to 10 students
int scores[10];
int num;
int average;
getScores(names, scores, num);
printScores(names, scores, num);
}
You need to write:
int num;
getScores(... &num);
printScores(... num);
And:
getScores(... int* n)
{
scanf("%d", n)
...
while (i < *n) { // Dereference the pointer `n` to get the value again.
With getScores(... int n) you just pass the current value of num and getScores() only modifies it's local copy of num (which is n); num itself it not changed.
Instead you must pass the "address of" (or "pointer to") num by using int* n.
The garbage you get is because num in main(), which you don't update at all, contains some undefined value (that could come from the processor stack, depending on the implementation of your platform and C compiler).
In your case this garbage/undefined value of num is coincidently higher than 4. This causes your scanned values to be printed plus a lot of again undefined values that are further up in names[] and scores[].
In C it's common to prefix pointers with p, so you may want to write pN instead above.
The above is to get things working. But there's more to say: Currently your arrays have a fixed size. If you'd enter 20 for n and/or enter very long names, your program will behave in undefined ways because your arrays are too small. If you want to stick to fixed sized arrays, you should at least check the value of num and the length of the entered names.
Take into account that the function getArrays is modifying variable n locally (since the function definition is like this:
void getArrays(char a[10][10], int b[10], int n )
and shoudl be like this:
void getArrays(char a[10][10], int b[10], int* n )
So possibly the value of n you are providing to printArrays is not initialized.
On the other hand,in printArrays the loop looks to be wrong defined:
for(j=0; j<n-1; j++)
should be
for(j=0; j<n; j++)
Newb here.
I'm probably missing something trivial but:
Here's the thing: http://i.imgur.com/8BmPci5.png
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Sort Numbers (zuerst)
int numbers [10];
int i,j;
j = 0;
int read;
printf("Input numbers: \n");
for (i=0;i<10;i++) {
scanf("%d",&read);
if (read == 27) {
break;
} else {
numbers[i] = read;
j++;
}
}
printf("j is: %d, i is: %d\n", j, i);
for (i=0;i<j;i++) {
printf("numbers[%d] is: %d\n", i, numbers[i]);
}
return 0;
}
Output:
Input numbers:
1
2
3
^[
j is: 10, i is: 10
numbers[0] is: 1
numbers[1] is: 2
numbers[2] is: 3
numbers[3] is: 3
numbers[4] is: 3
numbers[5] is: 3
numbers[6] is: 3
numbers[7] is: 3
numbers[8] is: 3
numbers[9] is: 3
I have a for loop (goes from 0 to <10). I also have a scanf inside wich scans for an int. If it ain't ESC (ASCII 27), then it puts it into an array and it increments the value of j. If it's an ESC, it ('s supposed to) break (exit the loop). Later, only j (or j-1) number of array items would be printed.
Issue: j (and i too) increments to 10, even if break is called at ~ i = 3 or 4.
Break supposed to exit the for loop without doing anything after it's called, right? Quote from BeginnersBook.com:
It is used to come out of the loop instantly. When a break statement is encountered inside a loop, the control directly comes out of loop and the loop gets terminated. It is used with if statement, whenever used inside loop.
What's wrong with my code? Thanks in advance.
You're being naughty in that you're not checking the return value of scanf, which will tell you the number of variables that were successfully populated. In your case, you want that to be 1 to signal that something was read into your variable read.
If you try to pass \033 (ASCII encoded ESC), then scanf will fail to parse that to an int. Then the previous value of read will be retained (which could give you undefined effects if it hasn't yet been set to anything), and read == 27 will almost certainly be 0. That behaviour accounts for the output you are observing.
If scanf does fail, you could try reading a char from the stream, and check if that is equal to \033.
Below is my code
main()
{
int c[ ]={2.8,3.4,4,6.7,5};
int j,*p=c;
for(j=0;j<5;j++){
printf(" %d ",*p);
++p; }
}
The output was
2 3 4 6 5
How the above code is executed?
it's executed exactly they way you think it's executed: you print the array elements in your for loop, however, you made the array elements as int, therefore, when printing 2.8 which is double, the compiler ignores whatever after the point, means, it sees it as 2 rather than 2.8
When you write the statement :
int c[ ]={2.8,3.4,4,6.7,5};
the decimal values are automatically converted to integers.So the array stores
2,3,4,6,5
So your output becomes as it is.
To work with decimals use float type variables.
float c[ ]={2.8,3.4,4,6.7,5};
The int c[] is integer.You can try it.
float c[] = { 2.8, 3.4, 4, 6.7, 5 };
float *p = c;
for (int j = 0; j<5; j++){
printf(" %f ", *p);
p = p+1;
}
if you use 'float j' instead of 'int j' and '%f' instead of '%d' you would get what you want.
Here due to the using of int j and %d, only the part before the decimal point of each number in the array is printed.
#include<stdio.h>
main
{
int x[]={1,2,3,4,5};
int i,*j;
j=x;
for(i=0;i<=4;i++)
{
printf("%u",j);
j++;
}
}
output:
65512
65514
65516
65518
65520
But when I change the printf to"
printf("%u",&j[i]);
Output is:
65512
65516
65520
65524
65528
Why the address differ by 2 in first case and 4 in second casee?
What is wrong with just printing j and printing &j[i]?
You get jumps of 4 in the second example because you are incrementing j and offsetting by i! Both of these contribute a difference of 2.
Note also that printf is not type-safe; it is up to you to ensure that the arguments match the format-specifiers. You have specified %u, but you've given it an int *, you should use %p for pointers.
First, just to make it clear, you are printing the pointer j, and not the pointed value, *j
Now, regarding the printed address. In your second example:
for(i=0;i<=4;i++)
{
printf("%u",&j[i]);
j++;
&j[i] equals to (j+i). i is incremented in each iteration, which contributes 2 to the pointer's value, and j is incremented too, which contributes another 2.
I have written a program that prints out the integers in the same order as the input with 5 numbers per line. That is, the first 5 integers will be printed in the first line; the next 5 integers in the next line; and so on. I was also was trying to print out the numbers in a bar chart format, like,
81-105 ( 1) x
56-80 ( 5) xxxxx
6-11(5) xxxxx
-1-5 (3) xxx
My program:
cntr=0;
while (fscanf(in, "%d", &a[i]) != EOF)
{i++;
fprintf(out, "%d-%d (%d) %s\n", A, B, k, x, cntr);
fprintf(out, "%d\n", k, cntr);
fprintf(out, "x", a[i]);
i++;
}
fprintf(out, "1864-2336 (%d)%s\n", k, x);
fprintf(out, "1391-1863 (%d)%s\n", k, x);
fprintf(out, "918-1390 (%d)%s\n", k, x);
fprintf(out, "445-917 (%d)%s\n", k, x);
fprintf(out,"-28-444 (%d)%s\n", k, x);
fclose(in);
fclose(out);
return 0;
}
You don't have to use a loop to print out your x's. You can declare a single string of x's that's as long as the maximum you will need, and then use a size specification in the printf call to control how many are printed. Here's a simple example to illustrate what I mean:
#include <stdio.h>
#include <string.h>
int main(void)
{
char maxBar[] = "xxxxxxxxxx";
size_t i;
for (i = 0; i < strlen(maxBar); i++)
{
printf("%lu: %-*.*s\n", (unsigned long) i, strlen(maxBar), i, maxBar);
}
return 0;
}
The output should look as follows:
0: __________
1: x_________
2: xx________
3: xxx_______
4: xxxx______
5: xxxxx_____
etc., where _ represents a space character.
A * in a printf conversion specifier indicates that a field width or precision specification is being passed as an argument to printf. Writing
printf("%-*.*s\n", 10, 2, "test");
is the same as writing
printf("%-10.2s\n", "test");
which, reading left to right, means
-: Left-justify the output
10: Minimum field width is 10 characters
.2: Precision (max number of chars printed) is 2
So the output looks like
te________
where _ represents a space character.
So, assuming you know how big your bar needs to be in advance, you can write something like
for (i = 0; i < k; i++)
{
printf("%d-%d (%d) %*.*s\n", lo[k], hi[k], ct[k], strlen(maxBar), ct[k], maxBar);
}
just do a loop to print the amount of x's you need
fprintf(out, "1864-2336 (%d)%s\n", k, x);
for(x=k;x>0;x--)
fprint(out,"%s","x");
fprintf(out,"\n");
Cheers!
/B2S
There are many ways to do this
It seems you already have somewhere declared an array of the values that user enters. a[]
In order to calculate the bar chart you could after user has entered all values, sort that array (e.g. using qsort()) then traverse the array checking the number of same values that occur in the array - this would be the number of '*' to print out
I think you should first let user enter the values, then do the output.
The code you show looks wrong, e.g. you increment 'i' twice in the while loop. You use the a[i] after the increment so it will not have the read value.
Also its good to use fgets/atoi instead when reading numbers that way invalid numbers will not cause your program to potentially crash.