Why does this program display seemingly random characters? (C++) - c++

Well, not random, because its the same every time, but
#include<iostream>
using namespace std;
int main()
{
char box[10][10];
for(int i=-1;i<11;i++)
{
cout<<"---------------------"<<endl<<"|";
for(int j=0;j<10;j++)
{
cout<<box[j][i]<<"|";
}
cout<<endl;
}
intx;cin>>x;
return 0;
}
outputs a series of international characters (well, not all of them are 'international' per se, but I get things like pi and spanish inverted question mark). Anyways, I know this is becuase the program access chars that have not been initialized, but why do particular values create particular symbols, what are the ASCII values of the symbols (if they have ASCII values) and how can I get the symbols without glitching my program?

Your loop over i doesn't make sense...
for(int i=-1;i<11;i++)
This will hit two indices that aren't valid, -1 and 10, when you reference box here:
cout<<box[j][i]<<"|";
It should be 0 to < 10 like the other loop.
Also you haven't initialized the contents of box to anything, so you're printing uninitialized memory. You have to put something into your "box" before you can take anything out.
The symbols themselves are probably extended ASCII, you can get at them through any extended ASCII table. This one came up first on google. For instance, you could do:
cout << "My extended ascii character is: " << (char)162 << endl;
to get a crazy international o.

For the same reason that
#include <iostream>
using namespace std;
int main()
{
int x;
cout << x;
}
displays a random value. Uninitialised variables (or arrays) contain garbage.

for(int i=-1;i<11;i++)
That line is suspect. -1 to 10? Should be 0 to 9.

The ASCII-code is
(int)(box[j][i])
You just print ordinary chars which are ASCII-characters with codes from 0 to 255.
When printing wchar_ts the same memory is interpreted as other characters.
Your loop should be in [0; 10[ not in [-1; 11[

The symbols displayed by the program depend on:
the contents that happens to be in the uninitialised variables, and
the locale of your computer or the encoding used in presentation.
A Unicode reference would probably be the best source for identifying the codes required to display particular symbols.
Consider that your users may not have the same encoding (or fonts with the correct symbols) selected by default. You should either check the current locale, or force one specific to your output to ensure your output renders the way you wish.

Related

Printing unicode Characters in C++

im trying to print a interface using these characters:
"╣║╗╝╚╔╩╦╠═╬"
but, when i try to print it, returns something like this:
"ôöæËÈ"
interface.txt
unsigned char* tabuleiroImportado() {
std::ifstream TABULEIRO;
TABULEIRO.open("tabuleiro.txt");
unsigned char tabu[36][256];
for (unsigned char i = 0; i < 36; i++) {
TABULEIRO >> tabu[i];
std::cout << tabu[i] << std::endl;
}
return *tabu;
}
i'm using this function to import the interface.
Just like every other possible kind of data that lives in your computer, it must be represented by a sequence of bytes. Each byte can have just 256 possible values.
All the carbon-based life forms, that live on the third planet from the sun, use all sorts of different alphabets with all sorts of characters, whose total number is much, more than 256.
A single byte by itself cannot, therefore, express all characters. The most simple way of handling all possible permutations of characters is to pick just 256 (or less) of them at a time, and assign the possible (up to 256) to a small set of characters, and call it your "character set".
Such is, apparently, your "tabuleiro.txt" file: its contents must be using some particular character set which includes the characters you expect to see there.
Your screen display, however, uses a different character set, hence the same values show different characters.
However, it's probably more complicated than that: modern operating system and modern terminals employ multi-byte character sequence, where a single character can be represented by specific sequences of more than just one byte. It's fairly likely that your terminal screen is based on multi-byte Unicode encoding.
In summary: you need to figure out two things:
Which character set your file uses
Which character set your terminal display uses
Then write the code to properly translate one to the other
It goes without saying that noone else could possibly tell you which character set your file uses, and which character set your terminal display uses. That's something you'll need to figure out. And without knowing both, you can't do step 3.
To print the Unicode characters, you can put the Unicode value with the prefix \u.
If the console does not support Unicode, then you cannot get the correct result.
Example:
#include <iostream>
int main() {
std::cout << "Character: \u2563" << std::endl;
std::cout << "Character: \u2551" << std::endl;
std::cout << "Character: \u2560" << std::endl;
}
Output:
Character: ╣
Character: ║
Character: ╠
the answer is use the unsigned char in = manner like char than a = unicode num
so this how to do it i did get an word like that when i was making an game engine for cmd so please up vote because it works in c++17 gnu gcc and in 2021 too to 2022 use anything in the place of a named a

how to detect non-ascii characters in C++ Windows?

I'm simply trying detect non-ascii characters in my C++ program on Windows.
Using something like isascii() or :
bool is_printable_ascii = (ch & ~0x7f) == 0 &&
(isprint() || isspace()) ;
does not work because non-ascii characters are getting mapped to ascii characters before or while getchar() is doing its thing. For example, if I have some code like:
#include <iostream>
using namespace std;
int main()
{
int c;
c = getchar();
cout << isascii(c) << endl;
cout << c << endl;
printf("0x%x\n", c);
cout << (char)c;
return 0;
}
and input a 😁 (because i am so happy right now), the output is
1
63
0x3f
?
Furthermore, if I feed the program something (outside of the extended ascii range (codepage 437)) like 'Ĥ', I get the output to be
1
72
0x48
H
This works with similar inputs such as Ĭ or ō (goes to I and o). So this seems algorithmic and not just mojibake or something. A quick check in python (via same terminal) with a program like
i = input()
print(ord(i))
gives me the expected actual hex code instead of the ascii mapped one (so its not the codepage or the terminal (?)). This makes me believe getchar() or C++ compilers (tested on VS compiler and g++) is doing something funky. I have also tried using cin and many other alternatives. Note that I've tried this on Linux and I cannot reproduce this issue which makes me inclined to believe that it is something to do with Windows (10 pro). Can anyone explain what is going on here?
Try replacing getchar() with getwchar(); I think you're right that its a Windows-only problem.
I think the problem is that getchar(); is expecting input as a char type, which is 8 bits and only supports ASCII. getwchar(); supports the wchar_t type which allows for other text encodings. "😁" isn't ASCII, and from this page: https://learn.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings , it seems like Windows encodes extended characters like this in UTF-16. I was having trouble finding a lookup table for utf-16 emoji, but I'm guessing that one of the bytes in the utf-16 "😁" is 0x39 which is why you're seeing that printed out.
Okay, I have solved this. I was not aware of translation modes.
_setmode(_fileno(stdin), _O_WTEXT);
Was the solution. The link below essentially explains that there are translation modes and I think phase 5 (character-set mapping) explains what happened.
https://en.cppreference.com/w/cpp/language/translation_phases

Writing a postfix calculator with a stack and iterator

#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main()
{
string blah("512+4*+3−");
stack<int> astack;
int a=0;
int b=0;
int result=0;
int final=0;
for (string::iterator count=blah.begin(); count != blah.end(); count=count+1)
{
if (isdigit(*count))
{
astack.push(*count);
cout<<" "<<*count<<" ";
}
else
{
a=astack.top();
astack.pop();
b=astack.top();
astack.pop();
if(*count=='+')
{
result = a+ b;
}
else if (*count=='-')
{
result=a-b;
}
else if(*count=='*')
{
result=a*b;
}
astack.push(result);
}
}
final=astack.top();
cout<<final;
}
My problem is whenever I run it, the code seems to segment fault. When I tried running it with the operator commented it the stack seems to pop two values and I'm not really sure why
As PaulMcKenzie pointed out, your minus sign in the blah string is some sort of weird unicode character that looks like a normal minus sign, but it isn't. Since it's some weird unicode character, it is actually being stored in more than one byte in the string's memory, meaning your iterator for-loop is iterating more times than you would expect!
Put a cout << blah.length() << endl; right after you declare blah, and you'll see that the length is more than the expected 9 characters.
Also, this program will not output the right answer even when the problem above is fixed. You need to convert your ascii number characters (which are in the integer range [48,57]) to the equivalent integer values before you do any calculations with them.
If the code you posted is the actual code, then there is an issue with the string you posted.
string blah("512+4*+3−");
That last character after the 3 is not an ASCII minus sign. It is a Unicode character 0x2212. Change this to an ASCII minus and rerun the program.
What may have happened is that you started out with an ASCII minus, copied the text to another app, and the app tries to "fancy up" the minus by replacing it with more aesthetic looking character. Then you may have copied the text from this app back to your source code editor.

Space vs null character

In C++, when we need to print a single space, we may do the following:
cout << ' ';
Or we can even use a converted ASCII code for space:
cout << static_cast<char>(32); //ASCII code 32 maps to a single space
I realized that, printing a null character will also cause a single space to be printed.
cout << static_cast<char>(0); //ASCII code 0 maps to a null character
So my question is: Is it universal to all C++ compilers that when I print static_cast<char>(0), it will always appear as a single space in the display?
If it is universal, does it applies to text files when I use file output stream?
No, it will be a zero(0) character in every compiler. Seems that the font you use renders zero characters as a space. For example, in the old times, DOS had a different image (an almost filled rectangle) for zero characters.
Anyway, you really should not output zero characters instead of spaces!
As for the text file part: open the outputted file using a hex editor to see the actual bits written. You will see the difference there!
On my computer, this code
#include <iostream>
int main() {
std::cout << "Hello" << static_cast<char>(0) << "world\n";
}
outputs this:
Helloworld
So no, it clearly doesn’t work.

What is wrong with my UVa code

I tried to solve this problem in UVa but I am getting a wrong answer and I cant seem to find the error
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2525
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int t,j,k,i=1;
char a[1000];
while(scanf("%d",&t)!=EOF && t)
{
int sum=0;
getchar();
gets(a);
k=strlen(a);
for(j=0;j<k;j++)
{ if(a[j]=='a'||a[j]=='d'||a[j]=='g'||a[j]=='j'||a[j]=='m'||a[j]=='p'||a[j]=='t'||a[j]=='w'||a[j]==32)
sum=sum+1;
else if(a[j]=='b'||a[j]=='e'||a[j]=='h'||a[j]=='k'||a[j]=='n'||a[j]=='q'||a[j]=='u'||a[j]=='x')
sum=sum+2;
else if(a[j]=='c'||a[j]=='f'||a[j]=='i'||a[j]=='l'||a[j]=='o'||a[j]=='r'||a[j]=='v'||a[j]=='y')
sum=sum+3;
else if(a[j]=='s'||a[j]=='z')
sum=sum+4;
}
printf("Case #%d: %d\n",i,sum);
i++;
}
return 0;
}
In the problem description there is a single number that indicates the number of texts that will be in the input afterwards. Your original code was trying to read the number before every row of input.
The attempt to read the number in each one of the rows will fail since the input character set does not include any digits, so you could be inclined to think that there should be no difference. But there is, when you try to read a number it will start by consuming the leading whitespace. If the input is:
< space >< space >a
The output should be 3 (two '0' and one '2' keys), but the attempt to read the number out of the line will consume the two leading whitespace characters and the later gets will read the string "a", rather than " a". Your count will be off by the amount of leading whitespace.
separate your code into functions that do specific things: read the data from the file, calculate the number of key presses for each input, output the result
Benefit:
You can test each function independently. It is also easier to reason about the code.
The maximum size of an input is 100, this means you only need an array of 101 characters( including the final \0) for each input, not 1000.
Since this question is also tagged C++ try to use std::vector and std::string in your code.
The inner for seems right at a cursory glance. The befit of having a specialized function that computes the number of key presses is that you can easily verify it does the correct thing. Make sure you check it thoroughly.