在C语言中,如何从屏幕的右手边而不是通常的左手边输出?

vjrehmav  于 2022-12-11  发布在  其他
关注(0)|答案(6)|浏览(271)

我正在编写一个游戏,其中我需要创建一些块。我把这部分编写得很完美,但问题是它们需要向屏幕的右手边对齐,而不是通常的左手边。现在,我知道了打印空白的长期方法来做到这一点,但我只是好奇,在C或C++中,是否有任何快捷方式可以从右边打印输出?

gkn4icbw

gkn4icbw1#

如果您要引用类似于控制台stdout(C++)的内容,例如cout,您可以使用以下两种方法之一:
http://www.cplusplus.com/reference/ios/right/
或iomanip库允许您具有许多文本格式化功能。例如:

cout << setw(20) << setiosflags(ios::right) << "Hello World!" << endl;

http://www.cplusplus.com/reference/iomanip/
别忘了#include <iomanip>
哦,请注意,要对齐的权利,我相信你必须设置宽度。
希望能有所帮助。

rdrgkggo

rdrgkggo2#

首先,计算出屏幕有多少列,这取决于你编程的平台;我无法帮助您,因为您没有指定平台。
对于实际打印,可以使用带有 field-width 说明符的printf,该说明符将文本右对齐到给定的field-width。
对于更复杂的情况,请看一下curses,一个用于终端编程的综合库。

bihw5rsg

bihw5rsg3#

在大多数常见的类Unix平台中,您可以使用ioctl系统调用:

#include <sys/ioctl.h>
#include <stdio.h>

int main()
{
    char *string = "Hello World";
    struct winsize w; 

    ioctl(0, TIOCGWINSZ, &w);
    printf("%*s\n", w.ws_col, string);
    return 0;
}
apeeds0o

apeeds0o4#

正如在其他建议的答案中所指出的,解决方案实际上取决于程序运行的系统类型,更重要的是取决于显示结果的设备类型。使用格式化控件(如printf或cout)进行对齐的变化本质上与自己在输出行中填充空格相同,但使用了更优雅的编程接口。
越过那些(因为它们看起来不是所请求的),显示设备的类型是感兴趣的。图形显示器普遍允许人们将文本放置在(可编程)设备。然而,字符单元设备(如终端)使其变得有点困难。任何你可能在POSIX系统上使用的设备都允许你在 cursor 位置写入文本,并使用 cursor-addressing 更改写入文本的位置。(Windows控制台提供了一个类似的界面,但细节不同--因为没有指定系统,所以大多数人认为POSIX是系统)。
使用光标寻址,您可以通过执行以下操作将给定的字符串写入屏幕右侧:

  • 求出屏幕的宽度,称之为W
  • 求出字符串的长度,调用L(实际上,您需要它将使用的屏幕上的 * 单元格 * 数--UTF-8字符串的 * 长度 *(以字节为单位)与其 * 宽度 * 不同)。
  • 将 * 光标 * 移动到屏幕当前行的单元格W - L(从零开始计数)。
  • 在屏幕上书写文本

虽然TIOCGWINSZ特性不是POSIX的一部分,但它得到了广泛的支持,并提供了一种获取屏幕宽度的方法,例如 * How to set the terminal's size? *。(一些系统支持使用TIOCGSIZE符号的类似调用,如 * Getting terminal width in C? * 中所述)。
在控制序列中选择较少的字符,而不是通过写空格来沿着行移动光标。移动光标有以下几种选择:

  • 硬编码控制序列,如HPA的控制序列(水平位置,绝对)。不建议使用,但可以在文档中找到,例如Linux的 * console_codes * 手册页或 * XTerm Control Sequences *。VT 100中没有此序列,许多终端仿真器都基于VT 100。但在ISO-6429中有文档记录。XTerm在1997年添加了它(Linux中没有那个时代的文档记录)。
  • 使用termcap来询问终端是否支持HPA(在termcaps中称为"ch"),或者使用带有参数的CUF(光标向前)(但这要求你知道你 * 在 * 哪里)。

char *hpa = tgetstr("cm", &areap); tgoto(hpa, W - L, 0); puts(mystring);

  • 使用curses,让它决定如何前往正确的位置:

int y, x; getyx(stdscr, y, x); move(y, W-L); addstr(mystring);

9o685dep

9o685dep5#

the following, some of the info found at: <http://wiki.bash-hackers.org/scripting/terminalcodes>
should greatly help you with handling the screen/cursor activities.

General useful ASCII codes

The Ctrl-Key representation is simply associating the non-printable characters from ASCII code 1 with the printable (letter) characters from ASCII code 65 ("A"). ASCII code 1 would be ^A (Ctrl-A), while ASCII code 7 (BEL) would be ^G (Ctrl-G). This is a common representation (and input method) and historically comes from one of the VT series of terminals.
Name    decimal octal   hex C-escape    Ctrl-Key    Description
BEL 7   007 0x07    \a  ^G  Terminal bell
BS  8   010 0x08    \b  ^H  Backspace
HT  9   011 0x09    \t  ^I  Horizontal TAB
LF  10  012 0x0A    \n  ^J  Linefeed (newline)
VT  11  013 0x0B    \v  ^K  Vertical TAB
FF  12  014 0x0C    \f  ^L  Formfeed (also: New page NP)
CR  13  015 0x0D    \r  ^M  Carriage return
ESC 27  033 0x1B    <none>  ^[  Escape character
DEL 127 177 0x7F    <none>  <none>  Delete character
Cursor handling
ANSI    terminfo equivalent Description
[ <X> ; <Y> H
[ <X> ; <Y> f   cup <X> <Y> Home-positioning to X and Y coordinates
:!: it seems that ANSI takes 1-1 as root while tput takes 0-0
[ H home    Home-positioning to root (0-0)
7   sc  Save current cursor position
8   rc  Restore current cursor position
:?: most likely a normal code like \b   cub1    move left one space (backspace)
VT100 [ ? 25 l  civis   switch cursor invisible
VT100 [ ? 25 h  cvvis   switch cursor visible
Erasing text
ANSI    terminfo equivalent     Description
[ K
[ 0 K   el  Clear line from current cursor position to end of line
[ 1 K   el1     Clear line from beginning to current cursor position
[ 2 K   el2:?:  Clear whole line (cursor position unchanged)
General text attributes
ANSI    terminfo equivalent Description
[ 0 m   sgr0    Reset all attributes
[ 1 m   bold    Set "bright" attribute
[ 2 m   dim Set "dim" attribute
[ 4 m   set smul unset rmul :?: Set "underscore" (underlined text) attribute
[ 5 m   blink   Set "blink" attribute
[ 7 m   rev Set "reverse" attribute
[ 8 m   invis   Set "hidden" attribute
Foreground coloring
ANSI    terminfo equivalent     Description
[ 3 0 m     setaf 0     Set foreground to color #0 - black
[ 3 1 m     setaf 1     Set foreground to color #1 - red
[ 3 2 m     setaf 2     Set foreground to color #2 - green
[ 3 3 m     setaf 3     Set foreground to color #3 - yellow
[ 3 4 m     setaf 4     Set foreground to color #4 - blue
[ 3 5 m     setaf 5     Set foreground to color #5 - magenta
[ 3 6 m     setaf 6     Set foreground to color #6 - cyan
[ 3 7 m     setaf 7     Set foreground to color #7 - white
[ 3 9 m     setaf 9     Set default color as foreground color
Background coloring
ANSI    terminfo equivalent     Description
[ 4 0 m     setab 0     Set background to color #0 - black
[ 4 1 m     setab 1     Set background to color #1 - red
[ 4 2 m     setab 2     Set background to color #2 - green
[ 4 3 m     setab 3     Set background to color #3 - yellow
[ 4 4 m     setab 4     Set background to color #4 - blue
[ 4 5 m     setab 5     Set background to color #5 - magenta
[ 4 6 m     setab 6     Set background to color #6 - cyan
[ 4 7 m     setab 7     Set background to color #7 - white
[ 4 9 m     setaf 9     Set default color as background color
Misc codes
Save/restore screen

Used capabilities: smcup, rmcup

You've undoubtedly already encountered programs that restore the terminal contents after they do their work (like vim). This can be done by the following commands:

# save, clear screen
tput smcup
clear

# example "application" follows...
read -n1 -p "Press any key to continue..."
# example "application" ends here

# restore
tput rmcup

These features require that certain capabilities exist in your termcap/terminfo. While xterm and most of its clones (rxvt, urxvt, etc) will support the instructions, your operating system may not include references to them in its default xterm profile. (FreeBSD, in particular, falls into this category.) If `tput smcup` appears to do nothing for you, and you don't want to modify your system termcap/terminfo data, and you KNOW that you are using a compatible xterm application, the following may be work for you:

echo -e '\033[?47h' # save screen
echo -e '\033[?47l' # restore screen

The following is more specific to cursor placement:
<http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html>

- Position the Cursor:
  \033[<L>;<C>H
     Or
  \033[<L>;<C>f
  puts the cursor at line L and column C.
- Move the cursor up N lines:
  \033[<N>A
- Move the cursor down N lines:
  \033[<N>B
- Move the cursor forward N columns:
  \033[<N>C
- Move the cursor backward N columns:
  \033[<N>D

- Clear the screen, move to (0,0):
  \033[2J
- Erase to end of line:
  \033[K

- Save cursor position:
  \033[s
- Restore cursor position:
  \033[u
tvz2xvvm

tvz2xvvm6#

假设我们要从右边打印'*'。总共要打印10颗星。为了更好地可视化,我将使用Sleep(1000)来查看打印星星的效果。下面是示例程序的外观:

#include<iostream>
#include<iomanip>
#include<Windows.h>

using namespace std;

int main() {    
    
    
    int n=10;
    for(int i=n;i>0;i--){

        cout<<setw(i+1)<<"*\r"<<flush;
        Sleep(1000);
    }
    return 0;
   
}

在这里,来自“iomanip”库的setw()函数被用来设置要打印的字符串的宽度。在“i+1”中额外的“+1”被用来解释字符“\r”,它是一个转义字符,在C++中被称为“回车”,它告诉终端仿真器将光标移动到行的开头,而不是下一行,比如\n。

相关问题