Reputation: 631
Question:
I want to make a C program that takes a string of space separated ints as input (positive and negative, variable number of digits) and converts the string to an int array.
There is another question on reading ints from a string input into an array on Stack Overflow but it doesn't work for numbers of digit length more than 1 or negative numbers.
Attempt:
#include <stdio.h>
int main () {
int arr[1000], length = 0, c;
while ((c = getchar()) != '\n') {
if (c != ' ') {
arr[length++] = c - '0';
}
}
printf("[");
for ( int i = 0; i < length-1; i++ ) {
printf("%d,", arr[i]);
}
printf("%d]\n", arr[length-1]);
}
If I enter the following into terminal:
$ echo "21 7" | ./run
$ [2,1,7]
This is the array I get: [2,1,7] instead of [21,7]
If I enter the following:
$ echo "-21 7" | ./run
$ [-3,2,1,7]
I get: [-3,2,1,7] instead of [-21,7] which makes no sense.
However, if I enter:
$ echo "1 2 3 4 5 6 7" | ./run
$ [1,2,3,4,5,6,7]
Note: I am assuming that the input it always a string of space separated integers.
Upvotes: 2
Views: 6182
Reputation: 3774
This is a barebones version (no error checking, a trailing space should be left after the numbers), I am sure you can pick up from here:
int main(void)
{
int c;
int i, num = 0, neg = 0;
while ((c = getchar()) != EOF) {
if (c != ' ') {
if (c == '-') {
neg = 1;
} else {
i = c - '0';
num = num * 10 + i;
}
} else {
(neg == 1) ? num *= -1 : num;
printf("%d\n", num + 2); // this is just to show that you indeed get an integer and addition works
num = 0;
neg = 0;
}
}
}
Upvotes: 4
Reputation: 4465
Complete program (adapted from this answer by @onemasse) (no longer needs invalid input to stop reading input):
#include <stdio.h>
#include <stdlib.h>
int main () {
int arr[1000], length = 0, c, bytesread;
char input[1000];
fgets(input, sizeof(input), stdin);
char* input1 = input;
while (sscanf(input1, "%d%n", &c, &bytesread) > 0) {
arr[length++] = c;
input1 += bytesread;
}
printf("[");
for ( int i = 0; i < length-1; i++ ) {
printf("%d,", arr[i]);
}
printf("%d]\n", arr[length-1]);
return 0;
}
From the scanf
/sscanf
man page:
These functions return the number of input items assigned. This can be fewer than provided for, or even zero, in the event of a matching failure.
Therefore, if the return value is 0, you know that it wasn't able to convert anymore.
Sample I/O:
$ ./parse
1 2 3 10 11 12 -2 -3 -12 -124
[1,2,3,10,11,12,-2,-3,-12,-124]
NOTE: I am currently unsure of exactly how this works. I will look into it. However, if anyone understands, please edit this post or leave a comment.
Upvotes: 4
Reputation: 84
Edited a little bit. But there is minus problem, yet. I ll look back later. If you tweak a little bit with this, I guess, it might work. You try your way. I ll try mine. But later.
#include <stdio.h>
int main () {
int arr[1000]={0}, length = 0, c, i;
while (1) {
c = getchar();
if(c=='-')
{
//minus sign has problem yet. I ll come back once I have better soln.
}
else if(c==' ' || c=='\n')
{
length-=2;
arr[length]= arr[length]*10 + arr[length+1];
length++;
if(c=='\n')
{
break;
}
}
else if (c != ' ') {
arr[length++] = c - '0';
}
}
printf("[");
for (i = 0; i < length-1; i++ ) {
printf("%d,", arr[i]);
}
printf("%d]\n", arr[length-1]);
}
Upvotes: 1
Reputation: 103
I don't do much c, but here's my go :)
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#define CHUNK 1000000
#define INT_COUNT 10000
int main(void) {
/*get all of the input*/
char temp_str[CHUNK] = "";
char* full_string = malloc(CHUNK * sizeof(char));
if (full_string == 0) {
printf("Memory Error\n");
exit(1);
}
int count = 2;
do {
fgets(temp_str, CHUNK, stdin);
strcat(full_string, temp_str);
full_string = realloc(full_string, count * CHUNK * sizeof(char));
if (full_string == 0) {
printf("Memory Error\n");
exit(1);
}
count++;
} while (strlen(temp_str) == CHUNK - 1 && temp_str[CHUNK - 2] != '\n');
//parse the input
char* token = strtok(full_string, " ");
int* arr = malloc(INT_COUNT * sizeof(int)), length = 0;
if (arr == 0) {
printf("Memory Error\n");
exit(1);
}
count = 1;
while (token != 0) {
arr[length] = atoi(token);
token = strtok(0, " ");
length++;
if (length == count * INT_COUNT) {
count++;
arr = realloc(arr, count * INT_COUNT);
if(arr == 0) {
printf("Memory Error\n");
exit(1);
}
}
}
free(full_string);
//print the integers
for (int i = 0; i < length; i++) {
printf("%d ", arr[i]);
if (i % 20 == 0 && i != 0) {
printf("\n");
}
}
free(arr);
return 0;
}
Upvotes: 1