【问题标题】:Converting a printf(); statement to a cout<<""; statement. C & C++ [duplicate]转换 printf();对 cout<<""; 的声明陈述。 C & C++ [重复]
【发布时间】:2024-01-15 05:28:01
【问题描述】:

我试图理解 printf() 但我只熟悉 C++ cout

void print_section(int n, int z){

    char dots[2*n+1];       // this makes a char array
    memset(dots,':',2*n+1); // this is similar to setfill()
    dots[2*n+1] = 0;

    for(int r = 0; r < n+1; r++){
        printf("%*.s|%.*s\\%.*s/%.*s|\n",z-n,"",r,dots,2*(n-r),dots,r,dots);
    }
    for(int r = n; r >= 0; r--){
        printf("%*.s|%.*s/%.*s\\%.*s|\n",z-n,"",r,dots,2*(n-r),dots,r,dots);
    }
}

【问题讨论】:

  • 您可以使用 boost::format 作为一种简单的解决方案
  • dots[2*n+1] = 0; 在数组外写入 - 未定义的行为。

标签: c++ c printf cout


【解决方案1】:

printf() 是如何工作的?

如果您想完全了解printf() 函数的工作原理,请参考:http://www.cplusplus.com/reference/cstdio/printf/

简单来说,"%*.s|%.*s\\%.*s/%.*s|\n" 就是这么说的

  1. 动态设置字段宽度并打印所需数量的''
  2. 打印|
  3. 动态设置字段宽度并打印所需数量的':'
  4. 打印\
  5. 动态设置字段宽度并打印所需数量的':'
  6. 打印/
  7. 动态设置字段宽度并打印所需数量的':'
  8. 打印|
  9. 打印换行符\n 以转到控制台中的下一行。

同样,您可以弄清楚"%*.s|%.*s/%.*s\\%.*s|\n" 将打印什么。

代码转换

假设您非常熟悉 C++。最好使用string 类,因为您可以轻松使用substr() 成员函数提取所需的dots 子字符串进行打印。您可以从here 了解setw() 的工作原理。转换后的代码如下。

#include <iostream> // Input.Output
#include <string> // string class
#include <iomanip> // setw() function
int main(){
    const int n=3,z=6;
    std::string _dots(2*n+1,':');
    for(int r = 0; r < n+1; r++){
        std::cout<<std::setw(z-n)<<""<<"|"<<_dots.substr(0,r)<<"\\"<<_dots.substr(0,2*(n-r))<<"/"<<_dots.substr(0,r)<<"|"<<std::endl;
    }
    for(int r = n; r >= 0; r--){
        std::cout<<std::setw(z-n)<<""<<"|"<<_dots.substr(0,r)<<"/"<<_dots.substr(0,2*(n-r))<<"\\"<<_dots.substr(0,r)<<"|"<<std::endl;
    }
    return 0;
}

输出

   |\::::::/|
   |:\::::/:|
   |::\::/::|
   |:::\/:::|
   |:::/\:::|
   |::/::\::|
   |:/::::\:|
   |/::::::\|

【讨论】:

  • 是的,这就是关键。 precision 可以由printf"%s" conversion specifier 控制以限制输出的字符数,在 C++ 中,您必须控制字符串大小本身与.substr()注意:你只需要std::string _dots(2*n,':');——不需要为nul-terminating字符:)保留空间@
  • 第一个"%*.s" 所发生的事情正是值得花一些时间研究的。关联的参数是z-n"",打印的最小长度(用空格填充,因为没有指定其他内容)和一个空字符串。 "%s" 将只是打印一个空字符串——基本上什么都不做——但由于*. 没有最小宽度为z-n 空格。最终结果:打印z-n 空格。不过,我不确定是否需要 .。如果有人能解释我是否遗漏了什么,我会很高兴。