简体   繁体   English

atoi()不适用于std :: string :: substr()

[英]atoi() Not Working with std::string::substr()

This is a snippet of my code: 这是我的代码的片段:

#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h> // atoi()


int main() {

    std::string line;

    std::ifstream numbers("numbertest.txt");

    if (numbers.is_open()) {
        while (std::getline(numbers, line)) {
            for (int i = 0; i < line.length() - 4; i++) {
                for (int n = 0; n < 5; n++) {
                    std::cout << atoi((line.substr(i, 5)[n]).c_str());
                }

I want to operate with numbers in groups of 5, from a file. 我想从文件中以5为一组的数字进行运算。 Why is atoi() not working here? 为什么atoi()在这里不起作用? It says "expression must have class type" under the second parentheses on the atoi line. 它在atoi行的第二个括号下说“表达式必须具有类类型”。

line.substr(i, 5) creates a temporary std::string containing 5 characters in line from position i line.substr(i, 5)创建包含在5个字符的临时的std :: string line从位置i

std::string foo = "hello world";
int i = 2;
std::cout << foo.substr(2, 5) << '\n';

would print "llo wo". 将打印“ llo wo”。

The [n] operator returns the n th character of the substring, which is of type char , you are then calling .c_str() on that character rather than on the substring. [n]运算符返回子字符串的第n个字符,该字符的类型为char ,然后在该字符而不是子字符串上调用.c_str()

You can avoid the .c_str() entirely by using std::stoi , eg 您可以使用std :: stoi完全避免使用.c_str() ,例如

std::cout << "line.substr(i, 5) = " << line.substr(i, 5) << '\n';
std::cout << std::stoi(line.substr(i, 5));

aoti and stoi both take a string representation of a number as their input and return the numeric value. aoti和stoi都以数字的字符串表示形式作为输入,并返回数字值。 For example: 例如:

std::string input = "123a";
// std::cout << input * 10 << '\n'; // illegal: input is a string, not a number.
int i = std::stoi(input); // converts to integer representation, i.e. 123
std::cout << i * 10 << '\n'; // outputs 1230

----- EDIT ----- -----编辑-----

You're actually asking all the wrong questions. 您实际上是在问所有错误的问题。 What you want to do is take an input pattern and output all of the patterns of 5 characters in it. 您要做的是输入一个输入模式,然后输出其中所有5个字符的模式。

Example input: "1020304050" Example output: 10203 02030 20304 03040 30405 04050 输入示例:“ 1020304050”输出示例:10203 02030 20304 03040 30405 04050

You don't need to convert these to numbers to output them, you can just output the characters. 您无需将它们转换为数字即可输出,只需输出字符即可。 The problem with your original code wasn't the conversion it was the incorrect sequence of operators. 您原始代码的问题不是转换,而是错误的运算符序列。

std::substring is expensive, it has to create a new, temporary string, copy characters from the original into it, and then return it, and it does it for every call. std::substring非常昂贵,它必须创建一个新的临时字符串,将原始字符复制到其中,然后将其返回,并在每次调用时都这样做。

The following should achieve what you're trying to do: 以下应该可以实现您想要做的事情:

while (std::getline(numbers, line)) {
    for (size_t i = 0; i < line.length() - 4; i++) {
        for (size_t n = 0; n < 5; n++) {
            std::cout << line[i + n];
        }
        std::cout << '\n';
    }
}

If you really want to invoke substr, you could also implement this as 如果您真的想调用substr,也可以将其实现为

while (std::getline(numbers, line)) {
    for (size_t i = 0; i < line.length() - 4; i++) {
        std::cout << line.substr(i, 5) << '\n';
    }
}

Here's a working demonstration: http://ideone.com/mXv2z5 这是一个工作示例: http : //ideone.com/mXv2z5

Try atoi( line.substr(i,5).c_str() ) 尝试atoi( line.substr(i,5).c_str() )

Or if you want for each character 或者如果您想要每个角色

std::cout << ((line.substr(i, 5)[n]) - '0');

Or even better 甚至更好

std::cout << (line[i+n]) - '0');

Note that: atoi is not ascii to integer. 请注意: atoi 不是 ascii的整数。 It converts a ctype string to number. 它将ctype字符串转换为数字。 For a single character, this conversion should be done using arithmetic or lookup table. 对于单个字符,此转换应使用算术或查找表完成。

Also there is no point converting characters to integer and then print it (back to chacters). 此外,将字符转换为整数然后再打印(返回到chacters)也没有意义。 You should better print digit character itself. 您最好打印数字字符本身。

Moreover in C++, I would prefer to use stringstream instead or atoi. 而且,在C ++中,我更喜欢使用stringstream或atoi。 On C++11 there are even more advanced solutions like sto*. 在C ++ 11上,还有更高级的解决方案,例如sto *。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std:string :: substr异常安全吗? - std:string::substr is exception safe? std::string::substr 返回的 object 的生命周期 - Lifetime of the object returned by std::string::substr std :: string.substr运行时错误 - std::string.substr Run Time Error 安全地将 std::string_view 转换为 int(如 stoi 或 atoi) - Safely convert std::string_view to int (like stoi or atoi) std :: string :: substr抛出std :: out_of_range但参数是限制的 - std::string::substr throws std::out_of_range but the arguments are in limit 从 std::variant 获取 substr <std::string, std::vector<std::string> &gt;&gt; 在 C++</std::string,> - Getting a substr from a std::variant<std::string, std::vector<std::string>>> in C++ 使用命令std :: string :: substr在C ++中拆分字符串 - Split the string in C++ using command std::string::substr 可以std :: string重载“substr”为rvalue * this并窃取资源吗? - Can std::string overload “substr” for rvalue *this and steal resources? &#39;std :: out_of_range&#39;what():basic_string :: substr:__ post - 'std::out_of_range' what(): basic_string::substr: __pos Whis可以更快地获取字符串std :: string :: erase或std :: string :: substr的一部分 - Whis is faster for getting a part of the string, std::string::erase or std::string::substr
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM