打印出 std::string 崩溃并出现分段错误
Printing out std::string crashes with segmentation fault error
我试图改进我对此处另一个问题的回复 How to cut the content of a string till a particular string or position? 以使用指针算法和 std::substr
所以我得到了以下
#include <iostream>
#include <string>
#include <cstring>
std::string getString(std::string fullString){
char string[80];
char* endString;
strcpy(string, fullString.c_str());
strtok(string, "|");
for(int i = 0; i < 4; i++){
endString = strtok(NULL, "|");
}
return fullString.substr(endString - string, std::string::npos);
}
int main( void ){
std::string str("{[(2015/11/30|01:07:53.357|-1227639088|DefaultThread|./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....");
std::cout << getString(str) << std::endl;
return 0;
}
但是,如果我将其更改为
,则会因分段错误而崩溃
#include <iostream>
#include <string>
#include <cstring>
std::string getString(std::string fullString){
char string[80];
char* endString;
strcpy(string, fullString.c_str());
strtok(string, "|");
for(int i = 0; i < 4; i++){
endString = strtok(NULL, "|");
}
std::cout << fullString.substr(endString - string, std::string::npos) << std::endl;
return fullString.substr(endString - string, std::string::npos);
}
int main( void ){
std::string str("{[(2015/11/30|01:07:53.357|-1227639088|DefaultThread|./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....");
std::cout << getString(str) << std::endl;
return 0;
}
程序运行正常,输出符合预期
./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....
./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....
为什么在第一种情况下会崩溃?
您输入的字符串是 120 字节宽。您的 C 字符串缓冲区为 80 字节宽。嗯。
使用 find 函数而不是这种容易出错的 C 废话!!
获取自上次以来的所有内容 |
:
#include <iostream>
#include <string>
#include <stdexcept>
std::string getString(const std::string& fullString)
{
size_t pos = fullString.rfind('|');
if (pos == std::string::npos)
throw std::runtime_error("Could not find a '|'!");
return fullString.substr(pos+1);
}
int main()
{
std::string str("{[(2015/11/30|01:07:53.357|-1227639088|DefaultThread|./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....");
std::cout << getString(str) << std::endl;
}
(live demo)
根据需要调整回扫第 2、3、4 |
。
您的程序有未定义的行为,因为 str
中存储的字符串长度超过 80 个字符。因此在这个声明中
strcpy(string, fullString.c_str());
你覆盖了超出数组字符串的内存。
此外,使用 C 函数 strtok
代替 class std::string
的成员函数 find
(或 rfind
)是一种糟糕的方法。
也不清楚为什么在循环中使用了幻数 4
for(int i = 0; i < 4; i++){
endString = strtok(NULL, "|");
}
我试图改进我对此处另一个问题的回复 How to cut the content of a string till a particular string or position? 以使用指针算法和 std::substr
所以我得到了以下
#include <iostream>
#include <string>
#include <cstring>
std::string getString(std::string fullString){
char string[80];
char* endString;
strcpy(string, fullString.c_str());
strtok(string, "|");
for(int i = 0; i < 4; i++){
endString = strtok(NULL, "|");
}
return fullString.substr(endString - string, std::string::npos);
}
int main( void ){
std::string str("{[(2015/11/30|01:07:53.357|-1227639088|DefaultThread|./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....");
std::cout << getString(str) << std::endl;
return 0;
}
但是,如果我将其更改为
,则会因分段错误而崩溃#include <iostream>
#include <string>
#include <cstring>
std::string getString(std::string fullString){
char string[80];
char* endString;
strcpy(string, fullString.c_str());
strtok(string, "|");
for(int i = 0; i < 4; i++){
endString = strtok(NULL, "|");
}
std::cout << fullString.substr(endString - string, std::string::npos) << std::endl;
return fullString.substr(endString - string, std::string::npos);
}
int main( void ){
std::string str("{[(2015/11/30|01:07:53.357|-1227639088|DefaultThread|./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....");
std::cout << getString(str) << std::endl;
return 0;
}
程序运行正常,输出符合预期
./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....
./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....
为什么在第一种情况下会崩溃?
您输入的字符串是 120 字节宽。您的 C 字符串缓冲区为 80 字节宽。嗯。
使用 find 函数而不是这种容易出错的 C 废话!!
获取自上次以来的所有内容 |
:
#include <iostream>
#include <string>
#include <stdexcept>
std::string getString(const std::string& fullString)
{
size_t pos = fullString.rfind('|');
if (pos == std::string::npos)
throw std::runtime_error("Could not find a '|'!");
return fullString.substr(pos+1);
}
int main()
{
std::string str("{[(2015/11/30|01:07:53.357|-1227639088|DefaultThread|./src/Myprogram.cpp:564|int main(int, argv**))]} Server Starting....");
std::cout << getString(str) << std::endl;
}
(live demo)
根据需要调整回扫第 2、3、4 |
。
您的程序有未定义的行为,因为 str
中存储的字符串长度超过 80 个字符。因此在这个声明中
strcpy(string, fullString.c_str());
你覆盖了超出数组字符串的内存。
此外,使用 C 函数 strtok
代替 class std::string
的成员函数 find
(或 rfind
)是一种糟糕的方法。
也不清楚为什么在循环中使用了幻数 4
for(int i = 0; i < 4; i++){
endString = strtok(NULL, "|");
}