从 C++ 中的字符串中删除非整数

发布于 2024-07-17 22:56:27 字数 911 浏览 3 评论 0原文

我的一本书中有一条评论说人们将逗号输入整数并弄乱了你的程序,但它没有详细说明。 这让我开始思考,所以我尝试编写一个小算法来获取 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 (或浮点数)?

There was a passing comment in a book of mine about people inputting commas into integers and messing up your program, but it didn't elaborate. That got me thinking, so I tried writing a little algorithm to take an std::string and remove all non-integer characters. This code compiles but skips over output. Why isn't anything being assigned to newstring? Does if(isdigit(fstring[i])) evaluate to true of the address it's pointing to hold a digit?

//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");
}

Secondary question, that perhaps belongs elsewhere: how do you convert a string to an int (or a floating point number)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

灯下孤影 2024-07-24 22:56:27

newstring 的长度为 0,因此 newstring[x] 其中 x=0 实际上是非法的。 您应该使用以下方法附加到字符串: newstring.append(1, fstring[i])

对于第二个问题,查找 atoi()、atof()、strtol(0, strtof() 函数。

newstring is of length 0, so newstring[x] where x=0 is actually illegal. You should append to the string using: newstring.append(1, fstring[i])

For the secondary question, look for atoi(), atof(), strtol(0, strtof() functions.

泪意 2024-07-24 22:56:27

字符串类似于数组,但字符串的默认构造函数创建一个空字符串。 为什么它应该分配比它需要的更多的内存? 即使确实如此,也没有说有多少,或者对于 fstring 的过滤副本是否足够大。 我印象深刻的是它不会崩溃。

一个简单的修改是将: 更改

std::string newstring;

为:

 std::string newstring(fstring.length(), '\0')

并在循环后添加:

 newstring.resize(x);

这将确保 newstring 在过滤期间至少有足够的空间(可能更多),并将被修剪到适当的大小当你完成过滤后。 您可能还对 std::remove_copy_if中的 a> 函数。

例如

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());

,对于将字符串转换为整数/浮点数,除了atoistrtolatofstrtof等已经提到的函数,您还可以使用 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 系列函数,您可能会对 scanfsscanf 感兴趣

 const char *s = "23";
 int result;
 sscanf(s, "%d", &result);

Strings are like arrays, but the default constructor for a string creates an empty string. Why should it allocate more memory than it needs? Even if it does, there's no saying how much, or if it will be big enough for a filtered copy of fstring. I'm impressed it doesn't crash.

A simple modification would be to change:

std::string newstring;

to:

 std::string newstring(fstring.length(), '\0')

And after the loop add:

 newstring.resize(x);

This will ensure that newstring will have at least enough room (probably more) during the filtration and will be trimmed down to the appropriate size when you are finished filtering. You may also be interested in the std::remove_copy_if function in <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());

As for converting a string to an integer / float, in addition to atoi, strtol, atof, strtof, etc. functions already mentioned you can also make using of the iostream library:

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

Also, if you are familiar with the printf family of functions you may be interested in scanf, sscanf

 const char *s = "23";
 int result;
 sscanf(s, "%d", &result);
夜光 2024-07-24 22:56:27

扩展 Shing Yip 的答案:

删除非数字:

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

或者如果你没有 boost:

#include <sstream>

int i = 0;
std::stringstream(fstring) >> i;

请注意,你必须初始化 i,否则它会赢如果 fstring 为空则不设置。

Expansion on Shing Yip's answer:

To remove non-digits:

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

I'm not sure why that static_cast is needed, though. I think something's ambiguous about isdigit without it. [Edit: If you don't do "using namespace std" then you don't need it, so it's my fault for being lazy writing example code.]

It's debatable whether this is any simpler than rolling your own loop:

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

And C++0x will have copy_if, which was left out basically by accident, and is trivial to implement:

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

To convert to int (or float):

int i = boost::lexical_cast<int>(fstring);

Or if you don't have boost:

#include <sstream>

int i = 0;
std::stringstream(fstring) >> i;

Note that you do have to initialize i, otherwise it won't be set if fstring is empty.

谈下烟灰 2024-07-24 22:56:27

删除数字:

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

To remove digits:

fstring.erase(
      std::remove_if(fstring.begin(), fstring.end(), &isdigit), 
      fstring.end());

To convert string to int/float/...:

int n1 = boost::lexical_cast<int>("123");
float n2 = boost::lexical_cast<float>("123.456");
婴鹅 2024-07-24 22:56:27
  • 字符串到浮点数:

您需要 #include

float strtof(const char *nptr, char **endptr);

例如:

 float f = strtof("3.4",NULL);
  • 字符串到整数

您需要 #include

int atoi(const char *numPtr);

请注意,这些是 C -函数,而不是 C++,因此您需要使用 std::string 上的 c_str() 方法来获取 C 字符串。

const char* c_str ( ) const;
  • string to floating point number:

You need to #include <cstdlib>

float strtof(const char *nptr, char **endptr);

For example:

 float f = strtof("3.4",NULL);
  • string to integer

You need to #include <cstdlib>

int atoi(const char *numPtr);

Notice that these are C - functions, not C++, so you need to use the c_str() method on std::string to get the C-string.

const char* c_str ( ) const;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文