How to Parse a String to an Int in C++

How to convert a string to integer in C?

There is strtol which is better IMO. Also I have taken a liking in strtonum, so use it if you have it (but remember it's not portable):

long long
strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr);

You might also be interested in strtoumax and strtoimax which are standard functions in C99. For example you could say:

uintmax_t num = strtoumax(s, NULL, 10);
if (num == UINTMAX_MAX && errno == ERANGE)
/* Could not convert. */

Anyway, stay away from atoi:

The call atoi(str) shall be equivalent to:

(int) strtol(str, (char **)NULL, 10)

except that the handling of errors may differ. If the value cannot be
represented, the behavior is undefined
.

How to parse sequence of integers from string in C?

As I noted in comments, it is probably best to use strtol() (or one of the other members of the strtoX() family of functions) to convert the string to integers. Here is code that pays attention to the Correct usage of strtol().

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *line = NULL;
size_t len = 0;

while (getline(&line, &len, stdin) != -1)
{
printf("Line input : [%s]\n", line);
int val = atoi(line);
printf("Parsed integer: %d\n", val);

char *start = line;
char *eon;
long value;
errno = 0;
while ((value = strtol(start, &eon, 0)),
eon != start &&
!((errno == EINVAL && value == 0) ||
(errno == ERANGE && (value == LONG_MIN || value == LONG_MAX))))
{
printf("%ld\n", value);
start = eon;
errno = 0;
}
putchar('\n');
}
free(line);
return 0;
}

The code in the question to read lines using POSIX getline() is almost correct; it is legitimate to pass a pointer to a null pointer to the function, and to pass a pointer to 0. However, technically, getline() returns -1 rather than EOF, though there are very few (if any) systems where there is a difference. Nevertheless, standard C allows EOF to be any negative value — it is not required to be -1.

For the extreme nitpickers, although the Linux and macOS man pages for strtol() state "returns 0 and sets errno to EINVAL" when it fails to convert the string, the C standard doesn't require errno is set for that. However, when the conversion fails, eon will be set to start — that is guaranteed by the standard. So, there is room to argue that the part of the test for EINVAL is superfluous.

The while loop uses a comma operator to call strtol() for its side-effects (assigning to value and eon), and ignores the result — and ignoring it is necessary because all possible return values are valid. The other three lines of the condition (the RHS of the comma operator) evaluate whether the conversion was successful. This avoids writing the call to strtol() twice. It's possibly an extreme case of DRY (don't repeat yourself) programming.

Small sample of running the code (program name rn89):

$ rn89
1 2 4 5 5 6
Line input : [ 1 2 4 5 5 6
]
Parsed integer: 1
1
2
4
5
5
6

232443 432435423 12312 1232413r2
Line input : [232443 432435423 12312 1232413r2
]
Parsed integer: 232443
232443
432435423
12312
1232413

324d
Line input : [324d
]
Parsed integer: 324
324

$

How to parse a string to an int in C++?

In the new C++11 there are functions for that: stoi, stol, stoll, stoul and so on.

int myNr = std::stoi(myString);

It will throw an exception on conversion error.

Even these new functions still have the same issue as noted by Dan: they will happily convert the string "11x" to integer "11".

See more: http://en.cppreference.com/w/cpp/string/basic_string/stol

How do I parse a string of numbers into a array of integers?

I think this will do what you want.

#include "stdafx.h"

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

#define MAX 100

int *parse_line(char *line, int *numInts) {
char sNumArray[MAX];
strcpy(sNumArray, line);
int *numbers = (int *) malloc(sizeof(int) * MAX);
char *tokens = strtok(sNumArray, " ");
for (int i = 0; ; i++) {
numbers[i] = atoi(tokens);
tokens = strtok(NULL, " ");
if (tokens == NULL) {
*numInts = i+1;
break;
}
}

return numbers;
}

int main() {
char *line = "10 10 10 4 4 4 9 9 9 2";
int numIntsExtracted = 0;
int *skyline = parse_line(line, &numIntsExtracted);

for (int j = 0; j < numIntsExtracted; ++j) {
printf("%d \n", skyline[j]);
}
return 0;
}

And the output I'm getting after running it.

10
10
10
4
4
4
9
9
9
2

Split a string into an integer array in C

A function with the signature implied in your post is not possible in C, because a function cannot return a dynamically-sized array. Two choices are possible here:

  • Pass an array and the max count into parseString, or
  • Return a pointer representing a dynamically allocated array, along with its actual size.

The first approach limits the size of the array to some number established by the caller; the second approach comes with a requirement to deallocate the array once you are done with it.

The function that follows the first approach would look like this:

void parseString(int data[], size_t maxSize);

The function that follows the second approach would look like this:

int *parseString(size_t *actualSize);

or like this:

void parseString(int ** data, size_t *actualSize);

The second case can be used to combine the two approaches, although the API would become somewhat less intuitive.

As for the parsing itself, many options exist. One of the "lightweight" options is using strtol, like this:

char *end = str;
while(*end) {
int n = strtol(str, &end, 10);
printf("%d\n", n);
while (*end == ',') {
end++;
}
str = end;
}

Demo.



Related Topics



Leave a reply



Submit