从asctime()中移除换行符

6
我想要去掉asctime()输出时间后的换行符。
string str;
time_t tt;
struct tm * ti;
time(&tt);
ti = localtime(&tt);
str = asctime(ti);
for (int i = 0; i < 2; i++)
    cout << str;

输出结果为:
fri apr 26 00:59:07 2019
fri apr 26 00:59:07 2019

但我希望它呈现出这种形式

fri apr 26 00:59:07 2019fri apr 26 00:59:07 2019
3个回答

11

由于换行符是最后一个字符,您只需要删除字符串中的最后一个字符即可。您可以通过调用pop_back来实现此操作。

str.pop_back();

在Windows上,换行符为\r\n,但在C和C++中,\n是平台无关的换行符。这意味着当您在文本模式下向stdout写入\n时,该字符将被转换为\r\n。您可以在任何地方使用\n,这样您的代码就具有跨平台性。


1
在 Windows 上,\r 也会在其中吗? - Nikos C.
2
我认为Windows应该只添加\n作为官方的C++行终止符(在读写文件时将其转换为内部一致性)。 - Galik
到目前为止,Visual Studio Code和Code::Blocks都只有\n。在Windows上还可以使用哪些编译器? - user5550963
1
@NikosC。不,这是C++运行时的工作,将系统换行符转换为'\n',就像在经典Mac上打印'\n'一样,它会被转换为输出中的'\r' - phuclv
1
@0x476f72616e 你想通过那个做什么?std::endl是一个返回std::basic_ostream引用的函数,而不是你可以打印的某个数值。即使你想知道换行符,这也行不通,因为在C和C++中,换行符始终是'\n',无论系统的换行符是什么(例如经典Mac的'\r')。 - phuclv
显示剩余4条评论

2

根据Kerndog73的回答,删除字符串的最后几个字符是可行的,但由于您正在使用C++,因此有更好的解决方案:使用std::put_time()流操作符:

Original Answer翻译成“最初的回答”

#include <iomanip>
#include <sstream>

// ...

auto tt = time(nullptr);
auto* ti = localtime(&tt);
std::stringstream sstream;
sstream << std::put_time(ti, "%c");
for (int i = 0; i < 2; i++)
    cout << sstream.str();

如果您不需要将时间存储为字符串,您可以直接将其打印出来:

最初的回答:

auto tt = time(nullptr);
auto* ti = localtime(&tt);
for (int i = 0; i < 2; i++)
    cout << std::put_time(ti, "%c");

-1

虽然您可以在循环中使用pop_back(),但是在C++11及更高版本中,您需要在删除之前检查最后一个字符以确保您正在修剪行尾而不是所需字符。您可以利用.c_str()成员函数和<cstring>提供的strcspn函数以及包含"\r\n"reject字符串来自动化该过程。在这里,strcspn返回不包含任何一个字符的字符数。

您可以使用不包括行尾的字符数将其传递给成员函数.erase(),以从第一个包括的行尾开始删除所有字符,例如:

    str.erase (strcspn (str.c_str(), "\r\n"));

您可以将相应数量的字符简单地复制到字符缓冲区中,例如:
    char trimmed[64] {};   // sufficiently sized to hold the asctime() return

    str.copy (trimmed, strcspn (str.c_str(), "\r\n"));

使用.erase(),您的第一个示例将如下:

#include <iostream>
#include <cstring>

int main (void) {
    time_t tt; 
    struct tm *ti; 
    time(&tt);
    ti = localtime(&tt);
    std::string str (asctime(ti));

    str.erase (strcspn (str.c_str(), "\r\n"));
    std::cout << "str: '" << str << "'\n\nor your output\n\n";

    for (int i = 0; i < 2; i++)
        std::cout << str;
    std::cout << '\n';
}

使用.copy(),你可以这样做:

#include <iostream>
#include <cstring>

int main (void) {
    time_t tt; 
    struct tm *ti; 
    time(&tt);
    ti = localtime(&tt);
    std::string str (asctime(ti));
    char trimmed[64] {};

    str.copy (trimmed, strcspn (str.c_str(), "\r\n"));
    std::cout << "str: '" << trimmed << "'\n\nor your output\n\n";

    for (int i = 0; i < 2; i++)
        std::cout << trimmed;
    std::cout << '\n';
}

示例使用/输出

两种情况下输出相同,例如:

$ ./bin/asctimetrim
str: 'Thu Apr 25 21:24:43 2019'

or your output

Thu Apr 25 21:24:43 2019Thu Apr 25 21:24:43 2019

这两种方便的附加方式,使用strcspn()来剪裁行尾,可以添加到您的C++工具箱中。


嗯,不好意思,能解释一下吗……通常这意味着你已经被@jww了。他是最气量狭窄的人之一。如果他不喜欢问题,那么他就会对每个答案进行投票。 (有点让我想起我的孩子在幼儿园时发脾气的情况--现在他们都上大学了,所以有证据表明人们可以克服这些问题)如果你注意到-他编辑了这个问题... - David C. Rankin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接