0

How do I store continuously read in input from the standard input in C? Similar to while (cin >> x) in C++?

Say I want to store a set of integers into an array/vector with no predefined size. In C++, I can do:

vector<int> vec;
while (cin >> x) {
  vec.push_back(x);
}

I haven't found anything online something similar to while (cin >> x).

The closest I've found for something similar to while (cin >> x) is:

int x;
while(scanf("%d", &x) == 1) {
  // do stuffs
}

But what this does is continually read through every input, including using the Enter key in the terminal. So it doesn't stop reading input from the terminal.

neil_ruaro
  • 368
  • 3
  • 15
  • 4
    A `std::vector` is a container that internally has a pointer to an array that was dynamically allocated. You can construct something like that yourself in C (e.g.: by using `realloc`) – UnholySheep Oct 05 '22 at 22:13
  • 2
    I would have thought that `while(scanf("%d", &x) == 1)` was a *very* good match to `while (cin >> x)`. Can you explain a little more how you're finding them different? – Steve Summit Oct 05 '22 at 22:41
  • Is the main question here how to do the stream-of-integers input, or how to replicate a `std::vector`? The question had been closed as a duplicate of [How to replicate vector in c?](https://stackoverflow.com/questions/4694401) and [C Vector/ArrayList/LinkedList](https://stackoverflow.com/questions/4701900), but it looks to me like the real question concerns the input, so I voted to reopen. BICBW. – Steve Summit Oct 05 '22 at 22:44
  • 1
    Both examples use `while()` so there's no difference there... Look at the _differences_ between the examples. C++ has a _magical_ `vector` object. You can't replace that with defining a single simple `int`... This is what you need to research... (as suggested by @UnholySheep: `realloc()`) – Fe2O3 Oct 05 '22 at 22:58
  • @SteveSummit yeah the main question is the stream-of-integer input. I'm finding them different because if I press the `Enter` key, it still asks for an input, instead of doing what I wanted the program to do with the input. My input consists of integers, and the program only stops asking for inputs if it's of type non-int (excluding whitespace) – neil_ruaro Oct 06 '22 at 02:57
  • You could use EOF (ctrl-d) to terminate input instead of a blank line with `scanf()`. If you don't like how it ignores newline then read it line (of max size) by line with `fgets()` instead then parse the line probably writing your own parser (i.e. not `atoi()` if you want to detect errors) or use `sscanf()`. vector block allocates, so you want to write a bit of code that reallocs with some factor (I forgot what the stl uses; <2) when out of space. There are a bunch of libraries out there too (see https://stackoverflow.com/questions/4310205/any-library-like-stl-vector-map-in-c) – Allan Wind Oct 06 '22 at 03:50
  • Also, don't overlook reading the whole thing as a string, then write a function to extract what you want. If your input is huge, it's easy to write to a file and you your function still works when you process file in blocks or mmap said file. – Allan Wind Oct 06 '22 at 04:03
  • @neil_ruaro I just compared the `scanf` and `cin >> x` loops, and at least on my machine, they perform *identically*. Single numbers on a line input as single numbers. Blank lines are ignored. Multiple numbers on a line input as multiple numbers. Non-numeric input, or control-D, terminates. This is all as I would expect. As I understand it, free-form stream input using `>>` in C++ is very, very similar, almost identical, to the free-form input that `scanf` does. – Steve Summit Oct 06 '22 at 16:56

1 Answers1

0

If the question is how to do free-form int input in C versus C++, scanf is indeed a good choice. This simple C program:

#include <stdio.h>

int main()
{
    int x;
    int i = 0;
    while(scanf("%d", &x) == 1) {
        printf("%d: %d\n", ++i, x);
    }
}

corresponds just about exactly to this simple C++ program:

#include <iostream>
using namespace std;

int main()
{
    int x;
    int i = 0;
    while (cin >> x) {
        cout << ++i << ": " << x << endl;
    }
}

For both programs, the input

11
22

33
44 55 66
x

yields the output

1: 11
2: 22
3: 33
4: 44
5: 55
6: 66

Note that, in both cases, blank lines are ignored, and multiple numbers on a line are read individually. Non-numeric input (here x) terminates the input.

On Unix and Linux, control-D can also be used to terminate the input; on Windows, control-Z can also be used.

If the question is how to store the integers into an automatically-growing vector, see How to replicate vector in c? or C Vector/ArrayList/LinkedList.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103