-8

What is wrong with this code? I need to convert string into float. m2 has an error in m2.length

#include <iostream>
#include <string>
#include <cstdlib>
#include <sstream>
using namespace std;

int main()
{
    float v2;
    char *m2 = "1 23 45 6";
    for (int i = 0; i < m2.length(); i++) //to convert every element in m2 into float
    {
        v2 = atof(&m2[i]);
    }
    printf("%.2f", v2);

    system("pause");
    return 0; 
}
ezzeddin
  • 499
  • 2
  • 5
  • 25
  • 4
    _"What is wrong with this code?"_ - Le'ts see...`using namespace std`, `atof`, `printf`, `system`, and `m2.length()`. – Captain Obvlious Apr 25 '15 at 11:25
  • `char*` doesn't provide a `length()` member function. You probably meant to use `std::string` instead, and the `size()` member function. – πάντα ῥεῖ Apr 25 '15 at 11:27
  • What is it that you actually want to achieve? Repeatedly assigning to `v2` inside a loop but then only printing `v2` once after the loop is finished does not sound very useful. – fredoverflow Apr 25 '15 at 11:27
  • If you want to convert every element to a float, one float will not suffice to hold your results. Use `std::vector values;` to store your floats. – Beta Carotin Apr 25 '15 at 11:32
  • @EzzEddinAbdullah I doubt your program really _works_ just by fixing my suggestions, there's a lot more problems, as the other commenters have mentioned. – πάντα ῥεῖ Apr 25 '15 at 11:41
  • @fredoverflow I need to convert each element in the array so that I can store them to make operations I already place *printf* inside the *for loop* – ezzeddin Apr 25 '15 at 11:42
  • Plus, you can't just iterate down the array and convert each into a number using the very unsafe `atof`. You're completely ignoring the place value of each number. And, what do you want spaces to mean? Right now, `atof` will probably return a 0 on the spaces, which is almost definitely not what you want. The easiest way to convert a String to a number is to write a `areAllNumbers` function that checks if the string is entirely numeric, then uses a `stringstream` to convert it if it is. – Carcigenicate Apr 25 '15 at 11:43
  • @πάνταῥεῖ string without using the pointer asterisk ** * ** and inside the loop to print all the element – ezzeddin Apr 25 '15 at 11:44
  • @Carcigenicate I made spaces because I would like to do a program that takes a matrix from the user as the form of matlab in brackets separating each row with *;* like this: **[1 2;3 4;5 6]** So after erasing semicolons and brackets. It puts such a string I will try the function you wrote, though. – ezzeddin Apr 25 '15 at 12:05
  • 1
    @EzzEddinAbdullah You need to include information like that, that completely changes your question. You aren't trying to convert a String to a float, you're trying to convert a space-delimited String into many floats. I don't think either of the answers address that. – Carcigenicate Apr 25 '15 at 12:08
  • @Carcigenicate Okay, I just meant at first how to convert string into float Is it the same with space-delimited String? – ezzeddin Apr 25 '15 at 12:18
  • Kind of. The problem it introduces is you have to cut up the string before you can convert each number. I think @fredoverflow's answer actually addresses that. I'm not sure though, I've never used `stringstreams` exactly like that. – Carcigenicate Apr 25 '15 at 12:23

4 Answers4

3

I need to convert each element in the array so that I can store them to make operations

Okay so how about you use a string stream to extract the numbers from the string into a vector?

#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>

int main()
{
    std::string input = "1 23 45 6";
    std::stringstream ss(input);
    std::istream_iterator<double> end;
    std::vector<double> output(std::istream_iterator<double>(ss), end);
}
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
1

There are too may things wrong with your code to explain each and every point. That's how I would do it:

float v2;
std::istringstream iss("1 23 45 6");
while(iss >> v2) {
    std::cout << v2 << std::endl;
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

Step by step analysis, for learning from the errors:

First there is no member function length() for an array of characters, so you should define string m2="..."; in order for the code to compile.

Then unfortunately your code would print only one number: the last. Why ? Because your printf() is outside the loop.

Once you've put it inside the loop, you'd have plenty of numbers, but more than you expect:
* the first iteration, it'd start with "1 23 45 6" => 1
* the second with " 23 45 6" => 23
* the third iteraton "23 45 6" => 23 again!
* the fourth iteration "3 45 6" => 3 (did you expect this ?)

So you'd have to jump from one number to the next. So instead of incrementing, you coud search for the next space, with function find_first_of():

for (int i = 0; i < m2.length(); i=m2.find_first_of(' ', i+1)) // jump to the next space
{
    v2 = atof(&m2[i]);
    printf("%.2f\n", v2);
}

Here the online demo.

Real c++ alternatives:

Have a look at πάντα ῥεῖ 's solution: that's the way we do it in C++

Christophe
  • 68,716
  • 7
  • 72
  • 138
0

Use string instead of char*, to make things a little easier.

For converting a given string to a numerical value, either use stringstream or atof().

Quick solution to your problem:

#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

int main()
{
    vector<float> myFloats;
    string m("1. 2.23 45 6456    72.8  46..");

    // First of parse given string and separate char groups that serve as a number
    // => only consider 0-9 and '.'
    if(m.size() == 0)
        return 1;

    string charGroup;
    for(int i=0; i<m.length(); i++)
    {
        if((isdigit(m.at(i)) || m.at(i) == '.'))
        {
            charGroup += m.at(i);
            if(i == m.length() - 1 && !charGroup.empty())
            {
                // in case given group is a numerical value
                myFloats.push_back((float) atof(charGroup.c_str()));

                // prepare for next group
                charGroup.clear();
            }
        }
        else if(!charGroup.empty())
        {
            if(m.at(i) == ' ')
            {
                // in case given group is a numerical value
                myFloats.push_back((float) atof(charGroup.c_str()));

                // prepare for next group
                charGroup.clear();
            }
            else charGroup.clear();
        }
    }

    // Print float values here
    if(!myFloats.empty())
    {
        cout << "Floats: ";
        for(int i=0; i<myFloats.size(); i++)
            cout << myFloats.at(i) << ", ";
    }

    getchar();
    return 0; 
}
neuronalbit
  • 358
  • 1
  • 3
  • 15