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
How to Execute a Command and Get the Output of the Command Within C++ Using Posix
How to Determine the Boost Version on a System
How to Convert String to Ip Address and Vice Versa
How to Get a Stack Trace for C++ Using Gcc With Line Number Information
What Are the Differences Between a Pointer Variable and a Reference Variable
What Uses Are There For "Placement New"
Strange Output in Comparison of Float With Float Literal
How to Print Out the Contents of a Vector
Array Index Out of Bound Behavior
How to Remove Code Duplication Between Similar Const and Non-Const Member Functions
How to Convert a Std::String to Int
Check If a Class Has a Member Function of a Given Signature
Detecting Endianness Programmatically in a C++ Program
Random Float Number Generation
How to Properly Overload the ≪≪ Operator For an Ostream