So I'm learning some stuff in College on C++, and the teacher and I got into a discussion on how to actually center text to the output screen. So my suggestion was to use setw but get the length of the string and the size of the console screen, do the algorithm and BAM we have truly centered text. He says the screen size is 80 but the screen can be resized, which doesn't work no matter what if the output is centered the the user starts resizing. Just a minor question I have, how to get the actual size of the console screen?
#include <iostream>
#include <string>
using namespace std;
const int SCR_SIZE = 80;//some way of telling size
int main(){
string randomText = "Hello User!";
cout << setw( ( (80 / 2) + (randomText.length() / 2 ) ) )
<< randomText
<< endl;
return 0;
}
Searched a little and found this bit
#include <cstdlib>
system("MODE CON COLS=25 LINES=22");
Would that work to set it on execution to make sure my size is what I want it to be? Just read through it so I'm not 100% positive if that in fact is a c++ library
You can #include <windows.h> and call GetConsoleScreenBufferInfo. To use this, you'll need a Windows handle to your standard output stream, which you can retrieve with GetStdHandle.
Be aware that the resulting code will be Windows-specific (whereas your current code is portable, so it should run fine on Linux, Mac OS, *BSD, etc.)
I found out that it's impossible to make the console application window to be bigger than a bit more than half of your screen, like it also is for cmd(command prompt). I'm just warning you that if you can't manually resize it to whatever size you want, you probably can't make it resize. Perhaps you want to try windows application or windows forms application?
Related
So I'm currently learning C++11 and I'm getting the hang of it. I want to play around with using a different language and since I'm Vietnamese, I want to make a C++ program that uses Vietnamese characters.
So how can I display Vietnamese characters the same way that English is displayed, which is like this:
cout << "Hello. This is English" << endl; //English
cout << "Chào. Đây là tiếng Việt." << endl; //Vietnamese
I heard that C++ has <locale>. Does it help make the Vietnamese characters appear?
You may be running into a problem with your environment. You don't say what platform/environment you are running in, but take the following program:
#include <iostream>
#include <cstdlib>
int main()
{
std::cout << u8"Chào thế giới!" << std::endl;
return EXIT_SUCCESS;
}
This yields the following output from iTerm on Mac OS X:
Chào thế giới!
With other (non-unicode) environments, using the same code, you may get UTF-8 characters interpreted as ASCII on output. I don't know what the Windows command line will yield, but if you are using an IDE, your IDE may or may not render UTF-8, independently of whether your shell does or doesn't.
Here's a web example.
https://code.sololearn.com/c39N9RN6b4Md/#cpp yields:
Chào thế giới!
But http://ideone.com/OkkUZs running exactly the same code yields:
Chào thế giới!
It's probably also worth pointing out that in C++ to properly process UTF-8 strings, count "characters", ensure your strings are valid UTF-8, etc. you will likely want to use a Unicode library--working with Unicode is non-trivial.
Personally, I have found both UTFCPP and TinyUTF8 to be excellent libraries - reasonably small, simple and effective.
Hope that helps.
#include <iostream>
#include <io.h>
#include <fcntl.h>
int main() {
_setmode(_fileno(stdout), _O_U16TEXT);
std::wcout << L"Chào. Đây là tiếng Việt.";
}
This is a solution that works for windows. Unfortunately it's not portable to other platforms.
For one programm I need to output Braille characters to a console.
I found a way to output unicode characters using code like:
#include <iostream>
#include "fcntl.h"
#include "io.h"
using namespace std;
int main() {
_setmode(_fileno(stdout), _O_U16TEXT);
wcout<<L"ĐĄßĞ"<<endl;
return 0;
}
And changing font of cmd to Lucida Console.
However, there is a problem that Braille characters aren't displayed is such a way. Actually, I can't even copy and paste them to code, because they appear blank. In Linux everything works(I can see, copy and paste these characters), but I need Windows application.
I guess there is some posiblity to use codes of this characters, I tried this way, but had no success.
Can anybody help me with this task?
You'll need to install a monospaced font that supports Unicode. To try this out, I used FreeMono.ttf from http://www.wazu.jp/gallery/Fonts_Braille.html.
After installing the font, edit the registry to add the font to the console's list of fonts: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont. There should be a 0 and 00 entry for Lucida Console and Consolas. Add another zero to the Value name for each font you want. I added 000 and set to FreeMono.
Restart the console, then edit its properties to choose the font. On Windows 10, you may have to enabled "Legacy Mode" in the console properties and restart the console before the font shows up. After selecting it, you can turn legacy mode back off again.
Here's the code I used:
#include <iostream>
#include "fcntl.h"
#include "io.h"
using namespace std;
int main() {
_setmode(_fileno(stdout), _O_U16TEXT);
wcout<<L"\u2876\u2877\u2878"<<endl;
return 0;
}
Output (screenshot):
Note: The font I chose didn't display ASCII nicely, so I don't recommend it, but the Braille was fine.
I am currently experimenting with xdotool to send keys to a process (I understand that it may not work for all processes that does not set _NET_WM_PID). I have trouble sending keystrokes to windows other from the focus. It does work if you are sending keystrokes to the CURRENTWINDOW. Below is the snippet that I used to test xdotool's functionality.
extern "C"{
#include <xdo.h>
}
//extern "C" xdo_window_search
#include <iostream>
#include <string.h>
using namespace std;
int main(){
xdo_t* p_xdo = xdo_new(NULL);
// Allocate memory for search query.
xdo_search_t s;
// Clear the allocated memory.
memset(&s, 0, sizeof(xdo_search_t));
// Set the search query.
s.pid = 1916;
s.max_depth = -1;
s.searchmask = SEARCH_PID;
s.require = xdo_search::SEARCH_ANY;
// Allocate memory for output
Window* windows;
int no_windows;
xdo_window_search(p_xdo,&s,&windows,&no_windows);
cout << no_windows << endl;
// Prints all windows' names with matching criteria
for( int i=0;i<no_windows;i++ ){
unsigned char * name;
int size;
int type;
xdo_get_window_name(p_xdo,windows[i],&name,&size,&type);
cout << i << ":" << name << endl;
}
for( int i=0;i<no_windows;i++ ){
xdo_type(p_xdo,windows[i],"Hello World",0);
}
//xdo_type(p_xdo,CURRENTWINDOW,"Hello World",0); // This does work.
return 0;
}
In additional to testing xdotool's functionality, I've looked into xdotool's source code. Interestingly, I found that they are using Xtest to send keystrokes to the focused window (CURRENTWINDOW) and X11's XSendEvent for other windows. I turned to xdotool because I couldn't get XSendEvent to work and Xtest cannot send keys to any other windows than the focused window.
Am I not using the xdotool correctly? Does xdotool not work with all *nix OS with X11?
[I am running this on Ubuntu 13.04.]
EDIT
So, it looks like that does work but not for all windows that it finds. For example, it works for firefox but not gedit and gnome-terminal although it found gedit and gnome-terminal by its pid. It behaves differently if I used CURRENTWINDOW.
So, it would be great if someone can explain why is this so. Like, is it related the force send flag in an XEvent?
Directly from the xdotool manual:
SENDEVENT NOTES
If you are trying to send key input to a specific window, and it does
not appear to be working, then it's likely your application is ignoring
the events xdotool is generating. This is fairly common.
Sending keystrokes to a specific window uses a different API than
simply typing to the active window. If you specify 'xdotool type
--window 12345 hello' xdotool will generate key events and send them
directly to window 12345. However, X11 servers will set a special flag
on all events generated in this way (see XEvent.xany.send_event in
X11's manual). Many programs observe this flag and reject these events.
It is important to note that for key and mouse events, we only use
XSendEvent when a specific window is targeted. Otherwise, we use XTEST.
Some programs can be configured to accept events even if they are
generated by xdotool. Seek the documentation of your application for
help.
Specific application notes (from the author's testing): * Firefox 3
seems to ignore all input when it does not have focus. * xterm can be
configured while running with ctrl+leftclick, 'Allow SendEvents' *
gnome-terminal appears to accept generated input by default.
I am currently writing an application which requires me to call GetWindowText on arbitrary windows and store that data to a file for later processing. Long story short, I noticed that my tool was failing on Battlefield 3, and I narrowed the problem down to the following character in its window title:
http://www.fileformat.info/info/unicode/char/2122/index.htm
So I created a little test app which just does the following:
std::wcout << L"\u2122";
Low and behold that breaks output to the console window for the remainder of the program.
Why is the MSVC STL choking on this character (and I assume others) when APIs like MessageBoxW etc display it just fine?
How can I get those characters printed to my file?
Tested on both VC10 and VC11 under Windows 7 x64.
Sorry for the poorly constructed post, I'm tearing my hair out here.
Thanks.
EDIT:
Minimal test case
#include <fstream>
#include <iostream>
int main()
{
{
std::wofstream test_file("test.txt");
test_file << L"\u2122";
}
std::wcout << L"\u2122";
}
Expected result: '™' character printed to console and file.
Observed result: File is created but is empty. No output to console.
I have confirmed that the font I"m using for my console is capable of displaying the character in question, and the file is definitely empty (0 bytes in size).
EDIT:
Further debugging shows that the 'failbit' and 'badbit' are set in the stream(s).
EDIT:
I have also tried using Boost.Locale and I am having the same issue even with the new locale imbued globally and explicitly to all standard streams.
To write into a file, you have to set the locale correctly, for example if you want to write them as UTF-8 characters, you have to add
const std::locale utf8_locale
= std::locale(std::locale(), new std::codecvt_utf8<wchar_t>());
test_file.imbue(utf8_locale);
You have to add these 2 include files
#include <codecvt>
#include <locale>
To write to the console you have to set the console in the correct mode (this is windows specific) by adding
_setmode(_fileno(stdout), _O_U8TEXT);
(in case you want to use UTF-8).
For this you have to add these 2 include files:
#include <fcntl.h>
#include <io.h>
Furthermore you have to make sure that your are using a font that supports Unicode (such as for example Lucida Console). You can change the font in the properties of your console window.
The complete program now looks like this:
#include <fstream>
#include <iostream>
#include <codecvt>
#include <locale>
#include <fcntl.h>
#include <io.h>
int main()
{
const std::locale utf8_locale = std::locale(std::locale(),
new std::codecvt_utf8<wchar_t>());
{
std::wofstream test_file("c:\\temp\\test.txt");
test_file.imbue(utf8_locale);
test_file << L"\u2122";
}
_setmode(_fileno(stdout), _O_U8TEXT);
std::wcout << L"\u2122";
}
Are you always using std::wcout or are you sometimes using std::cout? Mixing these won't work. Of course, the error description "choking" doesn't say at all what problem you are observing. I'd suspect that this is a different problem to the one using files, however.
As there is no real description of the problem it takes somewhat of a crystal ball followed by a shot in the dark to hit the problem... Since you want to get Unicode characters from you file make sure that the file stream you are using uses a std::locale whose std::codecvt<...> facet actually converts to a suitable Unicode encoding.
I just tested GCC (versions 4.4 thru 4.7) and MSVC 10, which all exhibit this problem.
Equally broken is wprintf, which does as little as the C++ stream API.
I also tested the raw Win32 API to see if nothing else was causing the failure, and this works:
#include <windows.h>
int main()
{
HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD n;
WriteConsoleW( stdout, L"\u03B2", 1, &n, NULL );
}
Which writes β to the console (if you set cmd's font to something like Lucida Console).
Conclusion: wchar_t output is horribly broken in both large C++ Standard library implementations.
Although the wide character streams take Unicode as input, that's not what they produce as output - the characters go through a conversion. If a character can't be represented in the encoding that it's converting to, the output fails.
I am trying to clear the console in C++. I know printing a number of newlines is a bad practice, as it can be slow and is not always reliable to completely clear the console window, but I have researched multiple options and have found almost no other solutions besides system("cls"), which is an even worse option.
Essentially, I have used the line cout << string(100, '\n'); but I am getting a near-unidentifiable error when I try to run the program.
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::basic_string<_Elem,_Traits,_Ax>' (or there is no acceptable conversion)
I have also researched this, and found that most explanations were too complicated for me as a beginning C++ programmer to understand, or completely unrelated to my problem.
My questions are (1) is there a way to fix this error, and (2) could there be a better, cross-platform way of clearing the console other than printing 100 newlines?
I also heard of Console.clear(), but I'm unsure if this is cross-platform. From what I've seen, it looks more like a Windows command. I've also heard of the curses library, which I was willing to research and use, until I read somewhere that it was not recommended to use the functions which I am familiar with coupled with the curses library functions.
Thank you in advance!
About your error... you have to...
#include <iostream>
#include <string>
using namespace std;
If you are using just windows use windows console API.
If you are using a linux\unix terminal, use escape codes.
You can do a #if to choose between the two methods.
On linux\unix use the write function defined in in this way:
write(1,"\E[H\E[2J",7); // we use ANSI escape sequences here.
Here is the microsoft page that explain how to do that.
http://support.microsoft.com/kb/99261
The really bad console api microsoft use for the console always makes me angry :) why 100 lines of code to clear a screen? :)
Now the if... you should create a clearscreen.h file and a clearscreen.cpp file.
In clearscreen.h we just put our function.
void clearconsole();
In clearscreen.cpp we put our code for both operative systems
#ifdef _WIN32 || _WIN64
#include <windows.h>
void clearconsole()
{
...
// 100 lines of codes copied from microsoft article
}
#else
#include <unistd.h>
void clearconsole()
{
write(1,"\E[H\E[2J",7);
}
#endif
At a guess, your immediate problem is probably that you're missing an #include <string>.
Probably the most portable way of dealing with the screen is via ncurses. It's included in POSIX and most POSIX-like systems, and available as a library for most others (e.g., Windows) as well.
Edit: For what it's worth, clearing the screen on Windows doesn't require anywhere close to 100 lines of code.
#include <windows.h>
void clear_screen(char fill = ' ') {
COORD tl = {0,0};
CONSOLE_SCREEN_BUFFER_INFO s;
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(console, &s);
DWORD written, cells = s.dwSize.X * s.dwSize.Y;
FillConsoleOutputCharacter(console, fill, cells, tl, &written);
FillConsoleOutputAttribute(console, s.wAttributes, cells, tl, &written);
SetConsoleCursorPosition(console, tl);
}
#ifdef TEST
int main(){
clear_screen();
return 0;
}
#endif
I'm the first to say that the code is more verbose than I'd like -- but it's less than ten lines, not to mention a hundred. Even the version in the MS knowledgebase is actually less than 40 lines -- of which many are blank or comments.
In fairness, however, I feel obliged to admit assembly language code writing directly to the hardware (or using the BIOS) does end up quite a bit shorter.
I know this is a complete necro. But I figured out what I feel is a rather neat solution and thought I'd share it just in case someone has this problem in the future.
void clearConsole() {
#ifdef _WIN32
#include <iostream>
static const char* CSI = "\33[";
printf("%s%c%s%c", CSI, 'H', CSI, '2J');
#else
#include <unistd.h>
write(1, "\E[H\E[2J", 7);
#endif
}