在 C++ 中从字符串中删除非整数
-
03-07-2019 - |
题
我的一本书中有一条评论说人们将逗号输入整数并弄乱了你的程序,但它没有详细说明。这让我开始思考,所以我尝试编写一个小算法来获取 std::string 并删除所有非整数字符。该代码可以编译,但会跳过输出。为什么没有任何东西被分配给 newstring ?if(isdigit(fstring[i])) 所指向的保存数字的地址的计算结果是否为 true?
//little algorithm to take the non-integers out of a string
//no idea on efficiency
#include <iostream>
#include <string>
int main()
{
std::cout << "Enter a number with non-integer characters: ";
std::string fstring;
getline(std::cin, fstring);
std::string newstring;
int i = 0, x = 0;
while (i != fstring.length())
{
if (isdigit(fstring[i]))
{
newstring[x] = fstring[i];
i++;
x++;
}
else
{
i++;
}
}
std::cout << std::endl;
std::cout << newstring;
system("PAUSE");
}
第二个问题,可能属于其他地方:如何将字符串转换为 int(或浮点数)?
解决方案
newstring的长度为0,因此newstring [x]其中x = 0实际上是非法的。您应该使用:newstring.append(1,fstring [i])
追加到字符串对于次要问题,请查找atoi(),atof(),strtol(0,strtof()函数。
其他提示
字符串类似于数组,但字符串的默认构造函数会创建一个空字符串。为什么要分配比它需要更多的内存?即使它确实如此,也没有说多少,或者它是否足够大,可以过滤fstring的副本。我印象深刻,它没有崩溃。
一个简单的修改就是改变:
std::string newstring;
为:
std::string newstring(fstring.length(), '\0')
在循环之后添加:
newstring.resize(x);
这将确保newstring
在过滤期间至少有足够的空间(可能更多),并在完成过滤后将其缩小到适当的大小。您可能还对std::remove_copy_if
中的 <algorithm>
功能感兴趣。
E.g。
struct isnotdigit { bool operator()(char c) { return !isdigit(c); } };
std::string newstring(fstring.length(), '\0');
std::string::iterator i = std::remove_copy_if(fstring.begin(),
fstring.end(), newstring.begin(), isnotdigit());
newstring.erase(i, newstring.end());
至于将字符串转换为整数/浮点数,除了atoi
,strtol
,atof
,strtof
等已经提到的函数之外,您还可以使用iostream库:
#include <sstream>
std::string integer("23");
std::istringstream iss(integer);
int result;
iss >> result;
std::string floatingpoint("3.14");
std::istringstream iss2(floatingpoint);
double result2;
iss2 >> result2;
另外,如果您熟悉printf系列函数,您可能对scanf
,sscanf
const char *s = "23";
int result;
sscanf(s, "%d", &result);
扩展成业的回答:
删除非数字:
#include <iostream>
#include <functional>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string fstring;
getline(cin, fstring);
fstring.erase(
remove_if(fstring.begin(), fstring.end(),
not1(ptr_fun(static_cast<int(*)(int)>(isdigit)))
),
fstring.end()
);
cout << fstring << "\n";
}
但我不确定为什么需要static_cast。如果没有它,我认为isdigit有些含糊不清。 [编辑:如果你不做<!>“;使用命名空间std <!>”;然后你不需要它,所以我懒得编写示例代码。]
这是否比滚动你自己的循环更简单是值得商榷的:
#include <iostream>
#include <string>
using namespace std;
int main() {
string fstring, ins;
getline(cin, ins);
for (string::iterator it = ins.begin(); it != ins.end(); ++it) {
if (isdigit(*it)) fstring.push_back(*it);
}
cout << fstring << "\n";
}
C ++ 0x将有copy_if,基本上是偶然的,并且实现起来很简单:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
int main() {
std::string fstring, ins;
std::getline(std::cin, ins);
std::copy_if(ins.begin(), ins.end(),
std::back_inserter(fstring), isdigit);
std::cout << fstring << "\n";
}
转换为int(或float):
int i = boost::lexical_cast<int>(fstring);
或者如果你没有提升:
#include <sstream>
int i = 0;
std::stringstream(fstring) >> i;
请注意,您必须初始化i,否则如果fstring为空则不会设置它。
删除数字:
fstring.erase(
std::remove_if(fstring.begin(), fstring.end(), &isdigit),
fstring.end());
将字符串转换为int / float /...:
int n1 = boost::lexical_cast<int>("123");
float n2 = boost::lexical_cast<float>("123.456");
- 字符串转浮点数:
你需要 #include <cstdlib>
float strtof(const char *nptr, char **endptr);
例如:
float f = strtof("3.4",NULL);
- 字符串到整数
你需要 #include <cstdlib>
int atoi(const char *numPtr);
请注意,这些是 C 函数,而不是 C++,因此您需要在 std::string 上使用 c_str() 方法来获取 C 字符串。
const char* c_str ( ) const;