Reputation: 2921
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. Why is atoi() not working here? It says "expression must have class type" under the second parentheses on the atoi line.
Upvotes: 2
Views: 3574
Reputation: 24269
line.substr(i, 5)
creates a temporary std::string containing 5 characters in line
from position i
std::string foo = "hello world";
int i = 2;
std::cout << foo.substr(2, 5) << '\n';
would print "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.
You can avoid the .c_str()
entirely by using std::stoi, e.g.
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. 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.
Example input: "1020304050" Example output: 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.
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
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
Upvotes: 5
Reputation: 30489
Try 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. It converts a ctype string to number. 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). You should better print digit character itself.
Moreover in C++, I would prefer to use stringstream instead or atoi. On C++11 there are even more advanced solutions like sto*.
Upvotes: 1