Parse String Containing Numbers into Integer Array

Parse string containing numbers into integer array

The end of file condition is not set upon a succesful parse, you have to check the state of the stream after parsing.

The second 76 is basically just pure chance. An unsuccesful parse leaves the target operand untouched, and because you did not initialize n, it can be anything.

A quickfix:

stream>>n;
if (stream)
cout<<n<<endl;

A cleaner fix:

int n;
while(stream >> n){
cout<<n<<endl;
}

To store those integers, the canonical way is to use std::vector if the number of elements is unknown. An example usage:

std::vector<int> values;
int n;
while(stream >> n){
...do something with n...
values.push_back(n);
}

However, you can use iterators over streams and use the following:

// Use std::vector's range constructor
std::vector<int> values(
(std::istream_iterator<int>(stream)), // begin
(std::istream_iterator<int>())); // end

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

Converting String Array to an Integer Array

You could read the entire input line from scanner, then split the line by , then you have a String[], parse each number into int[] with index one to one matching...(assuming valid input and no NumberFormatExceptions) like

String line = scanner.nextLine();
String[] numberStrs = line.split(",");
int[] numbers = new int[numberStrs.length];
for(int i = 0;i < numberStrs.length;i++)
{
// Note that this is assuming valid input
// If you want to check then add a try/catch
// and another index for the numbers if to continue adding the others (see below)
numbers[i] = Integer.parseInt(numberStrs[i]);
}

As YoYo's answer suggests, the above can be achieved more concisely in Java 8:

int[] numbers = Arrays.stream(line.split(",")).mapToInt(Integer::parseInt).toArray();  

To handle invalid input

You will need to consider what you want need to do in this case, do you want to know that there was bad input at that element or just skip it.

If you don't need to know about invalid input but just want to continue parsing the array you could do the following:

int index = 0;
for(int i = 0;i < numberStrs.length;i++)
{
try
{
numbers[index] = Integer.parseInt(numberStrs[i]);
index++;
}
catch (NumberFormatException nfe)
{
//Do nothing or you could print error if you want
}
}
// Now there will be a number of 'invalid' elements
// at the end which will need to be trimmed
numbers = Arrays.copyOf(numbers, index);

The reason we should trim the resulting array is that the invalid elements at the end of the int[] will be represented by a 0, these need to be removed in order to differentiate between a valid input value of 0.

Results in

Input: "2,5,6,bad,10"

Output: [2,3,6,10]

If you need to know about invalid input later you could do the following:

Integer[] numbers = new Integer[numberStrs.length];
for(int i = 0;i < numberStrs.length;i++)
{
try
{
numbers[i] = Integer.parseInt(numberStrs[i]);
}
catch (NumberFormatException nfe)
{
numbers[i] = null;
}
}

In this case bad input (not a valid integer) the element will be null.

Results in

Input: "2,5,6,bad,10"

Output: [2,3,6,null,10]


You could potentially improve performance by not catching the exception (see this question for more on this) and use a different method to check for valid integers.

How to split() a string to an array of integers

One option is using the Number constructor which returns a number or NaN:

var res = q.split(',').map(el => {
let n = Number(el);
return n === 0 ? n : n || el;
});

// > "The, 1, 2, Fox, Jumped, 3.33, Over, -0"
// < ["The", 1, 2, " Fox", " Jumped", 3.33, " Over", -0]

edit: If the above condition is confusing you can replace it with the following condition which was suggested by Bergi:

return isNaN(n) ? el : n;

In case that you want to trim the string elements you can also use the String.prototype.trim method:

return isNaN(n) ? el.trim() : n;

How to convert a string of numbers to an array of numbers?

My 2 cents for golfers:

b="1,2,3,4".split`,`.map(x=>+x)

backquote is string litteral so we can omit the parenthesis (because of the nature of split function) but it is equivalent to split(','). The string is now an array, we just have to map each value with a function returning the integer of the string so x=>+x (which is even shorter than the Number function (5 chars instead of 6)) is equivalent to :

function(x){return parseInt(x,10)}// version from techfoobar
(x)=>{return parseInt(x)} // lambda are shorter and parseInt default is 10
(x)=>{return +x} // diff. with parseInt in SO but + is better in this case
x=>+x // no multiple args, just 1 function call

I hope it is a bit more clear.

Convert a String containing space separated numbers into an integer array

In a functional way, using Java 8 streams:

int[] y = Arrays.stream(x.split(" ")).mapToInt(Integer::parseInt).toArray();

How to convert a string representation to an array integers?

The easy way is using .map() to create a new array along with using Number to parse each string into numbers.

var str = ["163600", "163601", "166881"];
var result = str.map(Number);
console.log(result);

/*Using `JSON.parse` first if your data is not an string array.*/
console.log(JSON.parse("[\"163600\", \"163601\", \"166881\"]").map(Number));

How to split a numeric string and then store it in an int array in c?

You have to convert string to int using strtol for example:

   char *p = strtok(b," ");
while( p != NULL)
{
arr[i++] = strtol(p, NULL, 10); // arr[i++] = p is wrong, because p is a string not an integer value
p = strtok(NULL," ");
}

When you print the value of array, use %d for integer value instead of %s. You use init_size is wrong. Because in the string, it has some space character. Your printing part should change to:

    for(int j = 0; j < i; j++)
printf("%d\n", arr[j]);

The complete code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char b[] = "1 2 3 4 5";
int init_size = strlen(b);
int arr[init_size];
int i = 0;

char *p = strtok(b," ");
while( p != NULL)
{
arr[i++] = strtol(p, NULL, 10);
p = strtok(NULL," ");
}

for(int j = 0; j < i; j++)
printf("%d\n", arr[j]);

return 0;
}

Convert String to int array in Java the fast way

Using String.split() is by far the most efficient when you want to split by a single character (a space, in your case).

If you are aiming for maximal efficiency when splitting by spaces, then this would be a good solution:

List<Integer> res = new ArrayList<>();
Arrays.asList(kraft.split(" ")).forEach(s->res.add(Integer.parseInt(s)));
Integer[] result = res.toArray(new Integer[0]);

And this works for any number of numbers.



Related Topics



Leave a reply



Submit