c++ - C++从 asctime ()删除换行符

我不想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



时间:

换行是最后一个字符,你只需要删除字符串中的最后一个字符。 你可以通过调用 pop_back 来做到这一点

 
str.pop_back();



 

在 Windows 上,换行是 rn,而 n 是C 和 C++ 独立的换行符。 这意味着当你在文本模式中将 n 写入到stdout时,字符将被转换为 rn 。 你只要使用 n,你的代码将是跨平台的。

按照kerndog73的回答,删除字符串的最后一个字符将会有效,但由于使用了 C ,你有一个更好的解决方案: std::put_time() 流操纵器:


#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");



根据手册 asctime() 返回 char *, 所以你可以做的是


#include <iostream>


#include <cstring>



int main (void) {


 time_t tt;


 struct tm * ti;


 time(&tt);


 ti = localtime(&tt);


 char* c_time = asctime(ti);


 int len = std::strlen(c_time);


 while (c_time[--len] <'0' || c_time[len]> '9')


 c_time[len] = '';


 std::string time (c_time);



 std::cout <<time;



 return 0;


}



编辑:每个注释都可以使用这个 C的 样式解决方案:


#include <iostream>


#include <cstring>



int main (void) {


 time_t tt;


 struct tm * ti;


 time(&tt);


 ti = localtime(&tt);


 char* c_time = asctime(ti);


 int len = std::strlen(c_time);



 time[strcspn (time.c_str(),"rn")] = 0;


 std::string time (c_time);



 std::cout <<time;



 return 0;


}



或者其他可以为 Windows ( 如果他们使用 r ) 工作的解决方案是:


#include <iostream>



int main (void) {


 time_t tt;


 struct tm * ti;


 time(&tt);


 ti = localtime(&tt);


 std::string time (asctime(ti));



 while ((time[time.size() - 1] <'0' || time[time.size() - 1]> '9')) 


 time.pop_back();



 std::cout <<time;



 return 0;


}



以下是改进的版本,不会删除任何字母或数字:


#include <iostream>



int main (void) {


 time_t tt; 


 struct tm * ti; 


 time(&tt);


 ti = localtime(&tt);


 std::string time (asctime(ti));



 while ( (time[time.size() - 1] <'0' || time[time.size() - 1]> '9') &&


 (time[time.size() - 1] <'a' || time[time.size() - 1]> 'z') &&


 (time[time.size() - 1] <'A' || time[time.size() - 1]> 'Z'))


 time.pop_back();



 std::cout <<time;



 return 0;


}



虽然你可以在循环中使用 pop_back(), 使用C 11及更高版本你可以在删除前检查最后一个字符,以确保修剪一个行结尾而不是想要的字符 你可以使用 .c_str() 成员函数和 这里,strcspn 返回不包含任何字符的字符数。

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


 str.erase (strcspn (str.c_str(),"rn"));



您可以简单地将该数量的字符复制到包机缓冲区,例如,


 char trimmed[64] {};//sufficiently sized to hold the asctime() return



 str.copy (trimmed, strcspn (str.c_str(),"rn"));



使用 .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(),"rn"));


 std::cout <<"str: '" <<str <<"'nnor your outputnn";



 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(),"rn"));


 std::cout <<"str: '" <<trimmed <<"'nnor your outputnn";



 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 工具箱中

...