What input operator can we use in C that ignores 'space' and accepts 'Enter' while taking array inputs - c

Consider an example:
5
1 0 5
1 1 7
1 0 3
2 1 0
2 1 1
Here, in the first line, 5 denotes the size of the array.
I'm entering five sequences one by one.
I want the first sequence ie. 1 0 5 to be stored in arr[0].
Note: 1, 0 and 5 are seperated by spaces.
However, arr[0] should contain 105 without any space.
I want to accept the next sequence into arr[1] only after pressing 'Enter'.
So that arr[1] should contain 117, arr[2] should contain 103 and so on up to arr[4].
Is there any operator that I can use for this?

There are no operators that do I/O in C at all, so no.
I also don't think there's any standard function with those semantics, they tend to view all whitespace as equal.
You should write your own, probably using fgets() to read in whole lines and then extracting the digits to convert to integers.

Related

Why does an array of text lines appear to have an extra level of container?

I'm reading a file using the "array of lines" mode of Dyalog's ⎕nget:
lines _ _ ← ⎕nget '/usr/share/dict/words' 1
And it appears to work:
lines[1]
10th
But the individual elements don't appear to be character arrays:
line ← lines[1]
line
10th
≢ line
1
⍴ line
Here we see that the first line has a tally of 1 and a shape of the empty array. I can't index into it any further; lines[1][1] or line[1] is a RANK ERROR. If I use ⊂ on the RHS I can assign the value to multiple variables at once and get the same behavior for each variable. But if I do a multiple assignment without the left shoe, I get this:
word rest ← line
word
10th
≢ word
4
⍴ word
4
At last we have the character array I expected! Yet it was not evidently separated from anything else hidden in line; the other variable is identical:
rest
10th
≢ rest
4
⍴ rest
4
word ≡ rest
1
Significantly, when I look at word it has no leading space, unlike line. So it seems that the individual array elements in the content matrix returned by ⎕nget are further wrapped in something that doesn't show up in shape or tally, and can't be indexed into, but when I use a destructuring assignment it unwraps them. It feels rather like the multiple-values stuff in Common Lisp.
If someone could explain what's going on here, I'd appreciate it. I feel like I'm missing something incredibly basic.
The result of reading a file with "array of lines" mode is a nested array. It is specifically a nested vector of character vectors where each character vector is a line from your text file.
For example, take \tmp\test.txt here:
my text file
has 3
lines
If we read this in, we can inspect the contents
(content newline encoding) ← ⎕nget'\tmp\test.txt' 1
≢ content ⍝ How many lines?
3
≢¨content ⍝ How long is each line?
12 5 5
content[2] ⍝ Indexing returns a scalar (non-simple)
┌─────┐
│has 3│
└─────┘
2⊃content ⍝ Use pick to get the contents of the 2nd scalar
has 3
⊃content[2] ⍝ Disclose the non-simple scalar
has 3
As you probably read from the online documentation, the default behaviour of ⎕NGET is to bring in a simple (non-nested) character vector with embedded new line characters. These are typically operating-system dependent.
(content encoding newline) ← ⎕nget'\tmp\test.txt'
newline ⍝ Unicode code points for line endings in this file (Microsoft Windows)
13 10
content
my text file
has 3
lines
content ∊ ⎕ucs 10 13
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
But with "array of lines" mode, you get a nested result.
For a quick introduction to nested arrays and the array model, see Stefan Kruger's LearnAPL book.
If you turn boxing on it's easier to see what's happening. Each element is an enclosed character vector. Use pick ⊃ instead of bracket index [] to get the actual item.
words ← ⊃⎕nget'/usr/share/dict/words'1
]box on -s=max
⍴words
┌→─────┐
│235886│
└~─────┘
words[10]
┌─────────┐
│ ┌→────┐ │
│ │Aaron│ │
│ └─────┘ │
└∊────────┘
10⊃words ⍝ use pick
┌→────┐
│Aaron│
└─────┘

Scanning n lines til EOF, each line containing spaces

I've been trying to search the Internet for answers but couldn't find any.
I'm trying to scan the following input:
100 0 1 3 10 3 6
101 0 4 4 2
200 1 2 5 1 2 3
300 1 7 6 1
Each line as a string and each string has whitespace between numbers.
I tried using:
while(scanf("%[^\n]s", str) != EOF)
but it's stuck in an infinite loop. It only scans the first line.
I also tried fgets until EOF but that gives me a compile error saying that I cannot compare a pointer
to an integer.
I just want to scan each line -> run it to a parser so I can separate the numbers into different variables -> do my calculations.
Thanks in advance.

Accesing two different rows simultaneously in C

Suppose I have a data set arranged in the following way
19 10 1 1
12 15 1 1
13 12 4 5
10 5 2 3
...
and so on, at a particular iteration in a for loop I have to read only the 1st and the 4th row and in the next iteration I have to access some other set of rows,for example
1st iteration:
1st row: 19 10 1 1
4th row: 10 5 2 3
i will access my data using the fscanf() function. But how will i ensure that I choose only the 1st and 4th rows or any two rows for that matter at a given iteration?
(I have not considered reading it into a 2D array since the size of data set is 10^8 )
Thank you.
As you read through your data (say, stored in a standard file), get byte offsets for rows by looking for row delimiters (a newline character). You can then read out rows based on the start and end byte offset with C pointer arithmetic on a FILE * and fseek(). Storing a few byte offsets (an eight byte long or equivalent, often) is cheap.

C: how to store integers by reading line by line with a random layout?

I need to read a file and store each number (int) in a variable, when it sees \n or a "-" (the minus sign means that it should store the numbers from 1 to 5 (1-5)) it needs to store it into the next variable. How should I proceed?
I was thinking of using fgets() but I can't find a way to do what I want.
The input looks like this:
0
0
5 10
4
2 4
5-10 2 3 4 6 7-9
4 3
These are x y positions.
I'd use fscanf to read one int at a time, and when it's negative, it is obviously the second part of a range. Or is -4--2 a valid input?

How can I iterate subranges in a "cyclic array"?

I'm trying to write the following Perl subroutine. Given are an array a of length n, an index i in the array (0<=i<n an upstream window length u and a downstream window length d.
I want to iterate over the values in the upstream window and the downstream window to i. In the simplest case, this will iterating over the values in a[i-u..i-1] (upstream window) and a[i+1..i+d] (downstream window).
For example: if my array is 1 2 3 4 5 6 7 8 9 10, i=5 and both window sizes are 2, the upstream values are simply 6 7 and the downstream values are 9 10.
However, there are two complications:
I would like to consider my array is cyclic. If i is relatively small (close to
0) or large (close to n), then one
of the windows may not fit in the
array. In that case, I want to look
at the array as a cyclic one. for
example, if my array is 1 2 3 4 5 6 7 8 9 10, i=8 and both window sizes
are 4, the upstream values are
simply 4 5 6 7, but the downstream
values are 9 10 1 2.
I would prefer some way to iterate
over these values without explicitly
copying them into a new array, since
they might be very long.
You can just get a list of indices using the range operator (..) by subtracting the upstream window from $i and adding the downstream window to $i. You will need to remember to skip the iterator when the iterator is equal to $i if you don't want that $ith value.
You will need to use the modulo operator (%) to keep the index within the bounds of the array. Given an array of size 11, we can see that by modifying the index with 11 it will always point to the right place in the array:
#!/usr/bin/perl
use strict;
use warnings;
for my $i (-22 .. 22) {
print "$i => ", $i % 11, "\n";
}
You may run into problems with huge numbers (i.e., numbers larger than what your platform holds in an unsigned integer), because Perl 5 changes the algorithm the modulus uses around there. It becomes more like C's fmod (but there are some differences).
You may also want to not use the integer pragma. It makes % faster, but you get the behavior of the C modulo operator. Neither ANSI nor ISO define what C should do with negative numbers, so you may or may not get a valid index back. Of course, so long as the version of C spits back either
X -5 -4 -3 -2 -1 0 1
X%5 0 -4 -3 -2 -1 0 1
or
X -5 -4 -3 -2 -1 0 1
X%5 0 1 2 3 4 0 1
it should be fine (if not very portable).
It looks like C99 defines the modulo operator to return the second case, so long as perl gets compiled with a C99 compiler (with the C99 flag on) it should be safe to use the integer pragma.

Resources