-1

I am working on a simulate file. The file has many rows with numbers, letters and characters.

Example:

    GR123,7894.5444,A,4687.5643,P
    GR456,1234.6556,A,9657.5686,P
    GR789,2344.3422,A,9786.8465,P
    GR987,6522.6354,A,3245.5754,P

I need to take the values before A and P (for the first row, 7894.5444 and 4687.5643).

How can I parse by position this string into an int? Already tried with:

    double exampleA = stoi(row.substr(6,9));
    double exampleP = stoi(row.substr(18,9));

But it gives me this error: request for member ‘substr’ in ‘row’, which is of non-class type ‘char*’

Also tried:

    char exampleA[9];
    char exampleP[9];

    memcpy(&exampleA, &row[6],sizeof(exampleA));
    memcpy(&exampleP, &row[6],sizeof(exampleP));

In order to convert the values after having separated them from the row but the memcpy buffer always brings the value of exampleP with exampleA like:

    A : 7894.5444
    P : 4687.5643?7894.5444
OsTeNg24
  • 274
  • 1
  • 15
shizde
  • 11
  • 5

2 Answers2

0

request for member ‘substr’ in ‘row’, which is of non-class type ‘char*’

Yeah, you can't call substr on a pointer. Perhaps you meant to store these things in a std::string instance?

As to your second attempt, there are multiple big problems with what you wrote:

  1. The buffers you're using are 9 bytes long, but the largest number in your example looks to be 10 bytes (4 + 1 + 4 + 1). You're overflowing your buffer and overwriting random memory in your process. Edit: or you would be if you wrote proper null-terminated strings.

  2. Related to the above, because it sort of hides the problem, don't use memcpy to copy strings. A much better first attempt would be strncpy to copy a substring to a buffer, though you still have to manually null-terminate it.

The reason why the P line shows both entries is that your compiler seems to put exampleA after exampleP on the stack, separated by a guard character, and since you don't null-terminate your strings, trying to display exampleP spills over into exampleA, which out of sheer luck seems to be followed by a null character.

Blindy
  • 65,249
  • 10
  • 91
  • 131
0

Since the data seems to be in a C string anyway, you might as well use std::strtod which has the advantage of not requiring you to copy the substring:

char* endp;
double exampleA = std::strtod(row+6, &endp);
double exampleP = std::strtod(row+18, &endp);

In both cases, you might want to double check that *endp == ',' and that no conversion error was signalled.

You could use std::strtod even with a std::string, of course. It's often the most efficient solution.

Note that strtod is locale-aware, so this might not work if the input doesn't correspond to your current locale (eg. Files using period fir decimals and commas for field separators while the locale uses comma and semicolon, respectively).

I'm not sure what you mean by converting a floating point number to an integer (truncate? round? multiply by 10,000?). So I didn't address that part of the question.

rici
  • 234,347
  • 28
  • 237
  • 341
  • It returns the error ```error: cannot resolve overloaded function ‘end’ based on conversion to type ‘char**’``` – shizde Oct 19 '20 at 15:02
  • 2
    You do `using namespace std;` and get problems. [Why is "using namespace std;" considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – 273K Oct 19 '20 at 15:07
  • I changed `end` to `endp` just in case. But I agree that `using namespace std;` creates more problems than its worth. – rici Oct 19 '20 at 15:11