Input non-printable ascii characters into scanf - c

So I've seen these two questions:
Input string with non printable chars
Inputting Non ASCII characters to scanf("%s")
And unfortunately these did not provide me for an answer I've needed
let's say I'm dependent within some output of a certain program and can't tell for sure which values I need to enter ahead of program's execution, I'd rather enter some input for example for this code:
#include <stdio.h>
int main()
{
char a[10] = {0};
printf("\n----------- %x\n", (unsigned int) a);
scanf("%s", a);
for(int i = 0; i < 10; i++)
printf("%d\n", (int) a[i]);
}
as an example, I'm waiting after the printf within the following program has reached, then
input -> some input containing non-printable ascii characters
program output-> 04
08
01
05
02
10
09
12
02
02 (All these are values of non-printable ascii characters)
and again I'm looking for a way to enter them directly
I'm not looking for a way to do this by implementing some
functionality within my code, my code is given as an example of a
program
When saying during runtime, I mean after the program has started running - hence the prints within my program have reached
I apologize if this was unclaer

On Linux you can type Control-v before a control character to enter it literally. So to type the character with code 0x04, type Control-vControl-d.

Related

Reading user input and displaying the ASCII equivalent

I'm writing a program that asks the user to input a number and displays the ASCII equivalent. It also displays the ASCII numbers of the 5 previous numbers and the five next numbers.
here's my code
#include <stdio.h>
displayASCIITABLE(int input);
int main()
{
int input;
printf("enter a number:\n");
displayASCIITABLE(input);
return 0;
}
displayASCIITABLE(int input)
{
printf("Number Character\n");
for(int i=input-5;i<=input+5;i++)
{
printf("%d %c\n",i,i);
}
}
The code works perfectly but some of the numbers ASCII value is not showing here's an example
for example, the ASCII value of 7 8 9 10 as shown in the image above
These numbers are probably escape codes, for example 10 is a newline. These types of characters aren't supposed to be shown but affect things like formatting
Not all character codes in ASCII are printable. Please, read about ASCII on Wikipedia, it will help you.
For instance, only characters from 32 ( , space) to 126 (~, tilde) are printable (i.e.: they are displayable on a terminal or in a text file, etc). There are also whitespace characters like \n, \r, \t, and others, that are considered control characters, but they do have some visual effect in a terminal (or in a text file, etc).
NOTE: the strange symbols you see in your terminal are not part of ASCII (intended as US-ASCII), but they are an extension to ASCII (but their codes are platform-dependent, since they rely on which character encoding your terminal has).
TL;DR: you cannot print any integer as it were a character; some character codes are just not displayable.

C statement with confusing conversion to integer?

In the following code there is an argument that I cant wrap my head around. I am supposed to create a pyramid comprised letters, with each line having a unique letter. Each letter/line is in a consecutive format, so line 1 could be A and line 2 would be B B, and line 3 being C C C.
The trouble is with the first For loop that is used to create the rows of the pyramid. Here is the troublesome portion: (input-'A'+1). "input" is a user assigned character variable. There is also a character variable named "alphabet" which has 'A' assigned to it, but unless I am mistaken that is not whats being used here.
From how my brain sees 'A' in this portion of the code it is a character literal. So with this thinking I created a small program using this portion of the entire statement as a printf statement. The variable "input" is user assigned. When i run it with %c as the conversion specifier it completes with no errors but there is no visible output, and it completes with a beep. When I run it with %d it runs and gives me the integer that I expect when subtracting input from A if they were both integers.
What am i missing? is 'A' being converted to an integer? I dont understand how it works, even though I see that it does work. Here is the original code:
#include <stdio.h>
int main()
{
int i, j;
char input, alphabet='A';
printf("Enter the uppercase character you want to print in the last row ");
scanf("%c", &input);
for (i=1; i<=(input- 'A'+1); ++i) {
for(j=1; j<=i; ++j)
{ printf("%c", alphabet); }
++alphabet;
printf("\n");
}
return 0;
}
Thank you for any help in clearing this up for me as I am learning from books and YouTube.
Character literals like 'A' are actually integers. char type is signed 8 bit integer type. 'A' is equal to 65. You can check the ASCII table too see which number represent which character. With i <= (input -'A'+ 1) the code test how far is the input character from 'A' basically which is the height of the pyramid. If the input were 'A' then i <= (input -'A'+ 1) would essentially i <= (65 - 65 + 1) which is i <= 1 there for only 1 iteration would happen printing a single A.
Since char is an integer, therefore ++alphabet will gives the next character in the alphabet.
The reason you have no output with printf with %c with your testing is most likely because you try to print a non printable character. Check the ASCII table and try to print some alphabet chars or numbers by using their decimal value. Like printf("%c", 65) should output A.
This little program will print the uppercase alphabet. Might help you see things more clearly.
#include <stdio.h>
int main()
{
for (int i = 65; i < 91; i++)
printf("%d printed as character is %c\n", i, i);
return 0;
}
Output
65 printed as character is A
66 printed as character is B
67 printed as character is C
68 printed as character is D
69 printed as character is E
70 printed as character is F
71 printed as character is G
72 printed as character is H
73 printed as character is I
74 printed as character is J
75 printed as character is K
76 printed as character is L
77 printed as character is M
78 printed as character is N
79 printed as character is O
80 printed as character is P
81 printed as character is Q
82 printed as character is R
83 printed as character is S
84 printed as character is T
85 printed as character is U
86 printed as character is V
87 printed as character is W
88 printed as character is X
89 printed as character is Y
90 printed as character is Z
Characters in C are stored as integers behind the scenes and every character has a corresponding value which you can see in the ASCII table. You can always print out the character as a %d and you'll get that character's int value. You can use that as an advantage while coding so you can increment, decrement, compare and do any sort of operation you would do with basic integers.
Also, post a copy of the code you are having trouble with so others and me can look for the error.

Printf partly ignores format string when printing newline via '%c'

I observed some behavior I can't explain myself when using printf to print a character via format-string.
It seems that when the character is newline ('\n'), the printf ignores everything up to (including) '%c' and just prints the remaining part.
Here is a minimal example (user input to disable optimization):
#include <stdio.h>
int main(){
int c;
scanf("%d", &c); //read char by ascii id
printf("FOO%cBAR (id %i)\n", c,c);
return 0;
}
Entering 45 (the code for '-') results in output "FOO-BAR", but entering 13 ('\n') just prints "BAR". This happens both in gcc 6.3.1 and clang 3.9.1, on -Og and -O3 optimisation levels, on an linux.
This should not be related to output buffering if I'm not mistaken.
Is this behavior intended?
That is because character 13 is "carriage return".
After that the first part of the message is over-written.
Newline is character 10.
From this answer :
\r is carriage return and moves the cursor back like if i will do-
printf("stackoverflow\rnine")
ninekoverflow
means it has shifted the cursor to the beginning of "stackoverflow" and overwrites the starting four characters since "nine" is four character long.
In this case,
BAR (id %i)\n
will overwrite "FOO".

In C, on variable value changes when reading characters and integers

I'm learning C and I have a question about a little problem that I had. Bear with me, I'm not going to write a full program just the segment of one for concision.
When writing a program that asks for a character and an integer (to create a triangle with said character and to the integer dimensions) I ran a problem where, once I prompted for the character, the value of an entirely different variable (int x;) was changed to 0. I solved the problem and got the program to work, but I don't completely understand why this was happening.
For example:
char sym[1];
int x;
printf("number:/n"); //asking for integer
scanf("%d", &x); //reading and assigning x to the value
printf("symbol:/n"); //asking for the character
scanf("%s", &sym); //reading and assign sym to the character
printf("%d",x); //printing the integer
printf("%s",sym); //printing the character
My output for x would change to 0 no matter what was read into it. This only occured AFTER reading the character.
When I change char sym[1] to char sym[8] or so, it doesn't change the value of x.
I know this must be some memory allocation thing, but does anyone know the details of why this happens? I know that changing the array size for sym makes the difference, but why would that change the value of variable x?
You should use %c, not %s, to read single characters. The %s specifier reads strings, which are null-terminated arrays of characters. Since the sym vector has enough space for only one character, the null terminator (a zero) is written one byte after sym, which happens to be on x
1.Possible initial memory layout:
(Each pair of numbers is one byte.)
00 00 00 00 00
-- -----------
sym[0] x
2.After scanf("%d", &x); reads "7":
00 07 00 00 00
-- -----------
sym[0] x
3A.If scanf("%s", &sym); reads "A":
(65 is the ASCII code for A)
65 00 00 00 00
-- -----------
sym[0] x
3B.If scanf("%s", &sym); reads "AAA":
65 65 65 00 00
-- -----------
sym[0] x'
Another issue in your code is that you shouldn't use & when scanfing strings, since sym is already the address you want to save to.
In this code behavior is undefined both in scanf and in printf.
Buffer is 1 character long; in c string is a an array of chars with '\0' terminating symbol (which is integer 0). So you need at least 2 chars to read one char as a string.
In this case you even can't print string, because it prints characters until find first 0.
scanf string like %<number>s, that will protect buffer from overflow. Or better use other functions to read strings
\n is newline, not /n
char sym[2];
int x;
printf("number:\n"); //asking for integer
scanf("%d", &x); //reading and assigning x to the value
printf("symbol:\n"); //asking for the character
scanf("%1s", &sym); //reading and assign sym to the character
printf("%d\n", x); //printing the integer
printf("%s", sym);
In your code x is zero, maybe because 0 overflows sym and overwrites x. But on my computer x is not zero, because x is located with some offset.

Parsing number into digits with scanf()

I want to type in a number that is 10 digits long, then put the digits into an array. But for some reason, I get this random 2-digit numbers that seem to have nothing to do with my input (??).
char number[10]; //number containing 10 digits
scanf("%s",number); //store digits of number
printf("%d\n",number[0]); //print the 1st digit in the number
printf("%d\n",number[1]); //print the 2nd digit in the number
Here is what I got:
Input:
1234567890
Output:
49
50
Actually, 49 should be 1, and 50 should be 2.
You are getting ASCII value of characters 1 and 2. Use %c specifier to print the digits.
printf("%c\n",number[0]);
Warning! Your code may invoke undefined behaviour!
But we'll talk about it later. Let us address your actual question first.
Here is a step by step explanation of what is going on. The first thing you need to know is that every character literal in C is actually an integer for the compiler.
Try this code.
#include <stdio.h>
int main()
{
printf("%d\n", sizeof '1');
return 0;
}
The output is:
4
This shows that the character literal '1' is represented as 4 byte integer by the compiler. Now, let us see what this 4 byte integer for '1' is using the next code here.
#include <stdio.h>
int main()
{
int a = '1';
printf("a when intepreted as int : %d\n", a);
printf("a when intepreted as char: %c\n", a);
return 0;
}
Compile it and run it. You'll see this output.
a when intepreted as int : 49
a when intepreted as char: 1
What do we learn?
The character '1' is represented as the integer 49 on my system. This is so for your system too. That's because in my system as well as yours, the compiler is using ASCII codes for the integers where '1' is 49, '2' is 50, 'A' is 65, 'B' is 66, and so on. Note that the mapping of the characters to these codes could be different for another system. You should never rely on these integer codes to identify the characters.
So when I try to print this value as integer (using %d as the format specifier), well what gets printed is the integer value of '1' which is 49. However, if we print this value as a character (using %c as the format specifier), what gets printed is the character whose integer code is 49. In other words, 1 gets printed.
Now try this code.
#include <stdio.h>
int main()
{
char s[] = "ABC123";
int i;
printf("char %%d %%c\n");
printf("---- -- --\n");
for (i = 0; i < 6; i++) {
printf("s[%d] %d %c\n", i, s[i], s[i]);
}
return 0;
}
Now you should see this output.
char %d %c
---- -- --
s[0] 65 A
s[1] 66 B
s[2] 67 C
s[3] 49 1
s[4] 50 2
s[5] 51 3
Does it make sense now? You need to use the %c format specifier when you want to print the character. You should use %d only when you want to see the integer code that represents that character.
Finally, let us come back to your code. This is how you fix it.
#include <stdio.h>
int main()
{
char number[10];
scanf("%9[^\n]", number);
printf("%c\n", number[0]);
printf("%c\n", number[1]);
return 0;
}
There are two things to note.
I have used %c as the format specifier to print the character representation of the digits read.
I have altered the format specifier for scanf to accept at most 9 characters only where the characters are not newline characters. This is to make sure that a user cannot crash your program by inputting a string that is far longer than 9 characters. Why 9 instead of 10?. Because we need to leave one cell of the array empty for the null-terminator. A longer input would overwrite memory locations beyond the allocated 10 bytes for the number array. Such buffer overruns lead to code that invoke undefined behaviour which could either cause a crash or kill your cat.
printf("%c\n",number[0]); //print the 1st digit in the number
printf("%c\n",number[1]);
should do the job for you, what you see are ascii values.
your number array is an array of char, and so every element of it is a char.
when you type:
printf("%d\n",number[0]);
you printing the chars as integers, and so you get the ASCII code for each char.
change your statement to printf("%c\n",number[0]); to print chars as chars not as ints
Warning! Your code invokes undefined behaviour!
char number[10]; // Can only store 9 digits and nul character
scanf("%s",number); // Inputting 1234567890 (11 chars) will overflow the array!
Use fgets instead:
#define MAX_LEN 10
char number[MAX_LEN];
if(fgets(number, MAX_LEN, stdin)) {
// all went ok
}
Once you have fixed this, you can fix the printing problem. You are printing the character code (number), and not the actual character. Use different type specifier:
printf("%c\n",number[0]);

Resources