How to print subscripts/superscripts on a CLI? - c++

I'm writing a piece of code which deals with math variables and indices, and I'd need to print subscripts and superscripts on a CLI, is there a (possibly cross-platform) way to do that? I'm working in vanilla C++.
Note: I'd like this to be cross-platform, but since from the first answers this doesn't seem to be possible I'm working under MacOS and Ubuntu Linux (so bash).
Thank you

Since most CLIs are really only terminals (pretty dumb ones mostly but sometimes with color), the only cross-platform way I've ever done this is by allocating muliple physical lines per virtual line, such as:
2
f(x) = x + log x
2
It's not ideal but it's probably the best you're going to get without a GUI.
Following you extra information as to what platforms you're mainly interested in:
With Ubuntu at least, gnome-terminal runs in UTF-8 mode by default so the following code shows how to generate the superscripts and subscripts:
#include <stdio.h>
static char *super[] = {"\xe2\x81\xb0", "\xc2\xb9", "\xc2\xb2",
"\xc2\xb3", "\xe2\x81\xb4", "\xe2\x81\xb5", "\xe2\x81\xb6",
"\xe2\x81\xb7", "\xe2\x81\xb8", "\xe2\x81\xb9"};
static char *sub[] = {"\xe2\x82\x80", "\xe2\x82\x81", "\xe2\x82\x82",
"\xe2\x82\x83", "\xe2\x82\x84", "\xe2\x82\x85", "\xe2\x82\x86",
"\xe2\x82\x87", "\xe2\x82\x88", "\xe2\x82\x89"};
int main(void) {
int i;
printf ("f(x) = x%s + log%sx\n",super[2],sub[2]);
for (i = 0; i < 10; i++) {
printf ("x%s x%s ", super[i], sub[i]);
}
printf ("y%s%s%s z%s%s\n", super[9], super[9], super[9], sub[7], sub[5]);
return 0;
}
The super and sub char* arrays are the UTF-8 encodings for the Unicode code points for numeric superscripts and subscripts (see here). The given program will output my formula from above (on one line instead of three), then another test line for all the choices and a y-super-999 and z-sub-75 so you can see what they look like.
MacOS doesn't appear to use gnome-terminal as a terminal program but references here and here seem to indicate the standard terminal understands UTF-8 (or you could download and install gnome-terminal as a last resort).

I'd need to print subscripts and superscripts on a CLI, is there a cross-platform way to do that?
Only if you have a Unicode-capable terminal, which is far from guaranteed. Unicode defines a limited number of sub- and superscript ‘compatibility characters’, you certainly can't use it on any old letter:
₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎ₐₑₒₓ
⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿⁱ
Even then you're reliant on there being a glyph for it in the console font, which is also far from guaranteed. Superscript 2 and 3 are likely to exist as they're present in ISO-8859-1; the others may well not work.

Related

ANSI escape code not working properly [C++]

I am using the ANSI escape code to print colored output.
I am getting proper colored output in vs code integrated terminal.
But when I am running the program in external command-prompt/Powershell, I am not getting the expected colored output.
My program looks something like this:
#define RESET "\033[0m"
#define RED "\x1B[31m"
#define GREEN "\x1B[32m"
int main(int argc, char** argv){
if(argc != 1){
std::cout << RED ">> Invalid Arguments!" RESET;
}else{
if(verify_password()){
...
...
...
}else{
std::cout << "\n>> " RED "Invalid Password!" RESET;
}
}
return 0;
}
Complete Code
NOTE: One weird thing I observed is that if I am entering the correct password then everything is working fine in both terminals(getting proper colors). But the problem is when either I am entering an incorrect password or an invalid amount of arguments
What might be the reason for this?
EDIT: I figured out a way to make it work. I find out that in order to make these escape codes work I need to have at least one call to system() function. But still, I am not sure how these things are connected.
Historically, consoles on Windows required use of the console API in the Windows SDK in order to do effects like color. But recent versions of Windows now support escape codes (and even UTF-8), but programs have to opt-in by calling SetConsoleMode with ENABLE_VIRTUAL_TERMINAL_PROCESSING. (Opting in preserves backward compatibility for older programs that aren't using escape codes or UTF-8.)
If you're getting color in some places and not others, then I'd guess there's a problem related to the state the terminal/console is in when sending the escape codes. For example, if the terminal thinks it's already processing an escape code and a new one begins, it might not recognize either. I suppose this might also be a problem if one part of the program uses escape codes but another part uses the Console API.

How do I save number of columns in Terminal with C++ to a variable?

I've been searching quite a lot, and all I've had are answers for C, not C++. I'm using Linux, so I won't be able to use windows.h
What I need to do is get the number of columns in the terminal window it's running, then print something in the middle with ncurses. How can I achieve this?
If you're going to be using ncurses, just use the facility (section 6.3.4) that exists in the library to do it:
int main(void) {
int rows, cols;
initscr();
getmaxyx(stdscr, rows, cols); // you now have the max for both axis
}
It's important to note that you should be refreshing these values (and the screen) upon receiving a SIGWINCH signal, or your windows will look rather odd if someone changes the height or width of their terminal program.
There is no C++ version of ncurses because it's not needed, but many prefer to create their own wrapper around it to get easier access to the functionality they want in the context of their application. The ncurses.h header will check to see if C++ is being used, and adjust accordingly:
#ifdef __cplusplus
extern "C" {
To use it, simply link it and use it procedurally, or use it in whatever class you have dealing with terminal I/O in your program.
Here is how :
int columns=system("tput cols");
You need to #include<stdlib.h>.
Then you can use mvprintw(y, x, "your text here") ; to print text wherever you want.
Note tput lines gives the number of rows, in case you want it too.
Note that i am ignoring the line I've been searching quite a lot, and all I've had are answers for C, not C++.. This is (one way of) how you do it, C or C++.
You may refer to this as an example.

Compile a program with local file embedded as a string variable?

Question should say it all.
Let's say there's a local file "mydefaultvalues.txt", separated from the main project. In the main project I want to have something like this:
char * defaultvalues = " ... "; // here should be the contents of mydefaultvalues.txt
And let the compiler swap " ... " with the actual contents of mydefaultvalues.txt. Can this be done? Is there like a compiler directive or something?
Not exactly, but you could do something like this:
defaults.h:
#define DEFAULT_VALUES "something something something"
code.c:
#include "defaults.h"
char *defaultvalues = DEFAULT_VALUES;
Where defaults.h could be generated, or otherwise created however you were planning to do it. The pre-processor can only do so much. Making your files in a form that it will understand will make things much easier.
The trick I did, on Linux, was to have in the Makefile this line:
defaultvalues.h: defaultvalues.txt
xxd -i defaultvalues.txt > defaultvalues.h
Then you could include:
#include "defaultvalues.h"
There is defined both unsigned char defaultvalues_txt[]; with the contents of the file, and unsigned int defaultvalues_txt_len; with the size of the file.
Note that defaultvalues_txt is not null-terminated, thus, not considered a C string. But since you also have the size, this should not be a problem.
EDIT:
A small variation would allow me to have a null-terminated string:
echo "char defaultvalues[] = { " `xxd -i < defaultvalues.txt` ", 0x00 };" > defaultvalues.h
Obviously will not work very well if the null character is present inside the file defaultvalues.txt, but that won't happen if it is plain text.
One way to achieve compile-time trickery like this is to write a simple script in some interpreted programming language(e.g. Python, Ruby or Perl will do great) which does a simple search and replace. Then just run the script before compiling.
Define your own #pramga XYZ directive which the script looks for and replaces it with the code that declares the variable with file contents in a string.
char * defaultvalues = ...
where ... contains the text string read from the given text file. Be sure to compensate for line length, new lines, string formatting characters and other special characters.
Edit: lvella beat me to it with far superior approach - embrace the tools your environment supplies you. In this case a tool which does string search and replace and feed a file to it.
Late answer I know but I don't think any of the current answers address what the OP is trying to accomplish although zxcdw came really close.
All any 7 year old has to do is load your program into a hex editor and hit CTRL-S. If the text is in your executable code (or vicinity) or application resource they can find it and edit it.
If you want to prevent the general public from changing a resource or static data just encrypt it, stuff it in a resource then decrypt it at runtime. Try DES for something small to start with.

swprintf fails with unicode characters in xcode, but works in visual studio

While trying to convert some existing code to support unicode characters this problem popped up. If i try to pass a unicode character (in this case im using the euro symbol) into any of the *wprintf functions it will fail, but seemingly only in xcode. The same code works fine in visual studio and I was even able to get a friend to test it successfully with gcc on linux. Here is the offending code:
wchar_t _teststring[10] = L"";
int _iRetVal = swprintf(_teststring, 10, L"A¥€");
wprintf(L"return: %d\n", _iRetVal);
// print values stored in string to check if anything got corrupted
for (int i=0; i<wcslen(_teststring); ++i) {
wprintf(L"%d: (%d)\n", i, _teststring[i]);
}
In xcode the call to swprintf will return -1, while in visual studio it will succeed and proceed to print out the correct values for each of the 3 chars (65, 165, 8364).
I have googled long and hard for solutions, one suggestion that has appeared a number of times is using a call such as:
setlocale(LC_CTYPE, "UTF-8");
I have tried various combinations of arguments with this function with no success, upon further investigation it appears to be returning null if i try to set the locale to any value other than the default "C".
I'm at a loss as to what else i can try to solve this problem, and the fact it works in other compilers/platforms just makes it all the more frustrating. Any help would be much appreciated!
EDIT:
Just thought i would add that when the swprintf call fails it sets an error code (92) which is defined as:
#define EILSEQ 92 /* Illegal byte sequence */
It should work if you fetch the locale from the environment:
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main(void) {
setlocale(LC_ALL, "");
wchar_t _teststring[10] = L"";
int _iRetVal = swprintf(_teststring, 10, L"A¥€");
wprintf(L"return: %d\n", _iRetVal);
// print values stored in string to check if anything got corrupted
for (int i=0; i<wcslen(_teststring); ++i) {
wprintf(L"%d: (%d)\n", i, _teststring[i]);
}
}
On my OS X 10.6, this works as expected with GCC 4.2.1, but when compiled with CLang 1.6, it places the UTF-8 bytes in the result string.
I could also compile this with Xcode (using the standard C++ console application template), but because graphical applications on OS X don't have the required locale environment variables, it doesn't work in Xcode's console. On the other hand, it always works in the Terminal application.
You could also set the locale to en_US.UTF-8 (setlocale(LC_ALL, "en_US.UTF-8")), but that is non-portable. Depending on your goal there may be better alternatives to wsprintf.
If you are using Xcode 4+ make sure you have set an appropriate encoding for your files that contain your strings. You can find the encoding settings on a right pane under "Text Settings" group.
Microsoft had a plan to be compatible with other compilers starting from VS 2015 but finally it never happened because of problems with legacy code, see link.
Fortunately you can still enable ISO C (C99) standard in VS 2015 by adding _CRT_STDIO_ISO_WIDE_SPECIFIERS preprocessor macro. It is recommended while writing portable code.
I found that using "%S" (upper case) in the formatting string works.
"%s" is for 8-bit characters, and "%S" is for 16-bit or 32-bit characters.
See: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
I'm using Qt Creator 4.11, which uses Clang 10.

Superscript in C++ console output

I'd like to have my program output "cm2" (cm squared).
How do make a superscript 2?
As Zan said, it depends what character encoding your standard output supports. If it supports Unicode , you can use the encoding for ²(U+00B2). If it supports the same Unicode encoding for source files and standard output, you can just embed it in the file. For example, my GNU/Linux system uses UTF-8 for both, so this works fine:
#include <iostream>
int main()
{
std::cout << "cm²" << std::endl;
}
This is not something C++ can do on its own.
You would need to use a specific feature of your console system.
I am not aware of any consoles or terminals that implement super-script. I might be wrong though.
I was trying to accomplish this task for the purpose of making a quadratic equation solver. Writing ax² inside a cout << by holding ALT while typing 253 displayed properly in the source code only, BUT NOT in the console. When running the program, it appeared as a light colored rectangle instead of a superscript 2.
A simple solution to this seems to be casting the integer 253 as a char, like this... (char)253.
Because our professor discourages us from using 'magic numbers', I declared it as a constant variable... const int superScriptTwo = 253; //ascii value of super script two.
Then, where I wanted the superscript 2 to appear in the console, I cast my variable as a char like this...
cout << "f(x) = ax" << (char)superScriptTwo << " + bx + c"; and it displayed perfectly.
Perhaps it's even easier just to create it as a char to begin with, and not worry about casting it. This code will also print a super script 2 to the console when compiled and run in VS2013 on my Lenovo running Windows 7...
char ssTwo = 253;
cout << ssTwo << endl;
I hope someone will find this useful. This is my first post, ever, so I do apologize in advance if I accidentally violated any Stack Overflow protocols for answering a question posted 5+ years ago. Any such occurrence was not intentional.
Yes, I agree with Zan.
Basic C++ does not have any inbuilt functionality to print superscripts or subscripts. You need to use any additional UI library.
std::cout << cm\x00B2;
writes cm^2.
For super scripting or sub scripting you need to use ascii value of the letter or number.
Eg: Super scripting 2 for x² we need to get the ascii value of super script of 2 (search in google for that) ie - 253. For typing ascii character you have to do alt + 253 here, you can write a any number, but its 253 in this case.
Eg:-cout<<"x²";
So, now it should display x² on the black screen.
Why don't you try ASCII?
Declare a character and give it an ASCII value of 253 and then print the character.
So your code should go like this;
char ch = 253;
cout<<"cm"<<ch;
This will definitely print cm2.