-2

I have a file of numbers that looks like this;

003 334 556 283 294 102 586 294 ...

Each 3 digit number is separated by space, on one line.

What I would like, is to be able to read a number, digit by digit, until it hits a space, then move the cursor again (so the space is overcome) and restart the loop with the next number. Each digit would be assigned to an index within an array. This array would be overwritten on the next loop - which is fine.

E.g. 003

The cursor starts at the start of the file. Reads 0, assigns to array[0], reads 0, assigns to array[1], reads 3, assigns to array[2], reads space, does some other stuff, then starts the loop again.

Does the cursor reading the file know when it has hit a space? Is there a way to use this to restart my loop? I understand using feof for the end of the file, is there something similar for whitespace?

I have more to do once the digits are all read into the array, that's why I would like them in that format. Once I have finished with that number of 3 digits, I want to move onto and do the same with the next and so on.

I hope this makes sense!

I couldn't find anything to help me, hence why I've asked on here. Obviously, if there is an answer already written, point me in that direction!

A. Lord
  • 157
  • 1
  • 3
  • 10

2 Answers2

2

I think I'd probably use:

char array[4];

while (scanf(" %1[0-9]%1[0-9]%1[0-9]", &array[0], &array[1], &array[2]) == 3)
{
    /* Process array */
    /* Maybe map character code to pure numbers:
    array[0] -= '0'; array[1] -= '0'; array[2] -= '0';
    */
}

The leading space skips optional white space (zero or more occurrences of a white space character — blank, tab, newline). The %[…] scan-set notation does not skip white space (neither does %c nor %n; all other conversion specifiers do). The scan-sets ensure that there are 3 digits to read.

The array needs to be of size 4 to allow for each scan set to null terminate its output. This verges on grubby, though the behaviour is well defined as the implementation is required to achieve the effect of a sequence point between each conversion specification.

About the only objection could be "it doesn't mind if the input is 987654321". If that's a problem, then use:

char array[4];
char dummy;

while (scanf(" %1[0-9]%1[0-9]%1[0-9]%1[ ]", &array[0], &array[1], &array[2], &dummy) == 4)
{
    …
}

This does insist on a blank after the last triplet of digits. If you don't mind a newline appearing, add it to the dummy scan set: %1[ \n]. It allows multiple white spaces between the triplets of digits. If that's a problem, then you need to fall back on getchar(). On the whole, though, it is better to be tolerant in what you accept as input (Postel's Law).


Test code

#include <stdio.h>

int main(void)
{
    char array[4];

    // array[3] = 'X';
    while (scanf(" %1[0-9]%1[0-9]%1[0-9]", &array[0], &array[1], &array[2]) == 3)
    {
        printf("0 = %c, 1 = %c, 2 = %c, 3 = %d\n", array[0], array[1], array[2], array[3]);
    }
    return 0;
}

Sample data (with a blank after the 208):

079 857 130 962 414 287 208 

Sample output:

0 = 0, 1 = 7, 2 = 9, 3 = 0
0 = 8, 1 = 5, 2 = 7, 3 = 0
0 = 1, 1 = 3, 2 = 0, 3 = 0
0 = 9, 1 = 6, 2 = 2, 3 = 0
0 = 4, 1 = 1, 2 = 4, 3 = 0
0 = 2, 1 = 8, 2 = 7, 3 = 0
0 = 2, 1 = 0, 2 = 8, 3 = 0
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

If you want to read numbers from the file then you can use fscanf("%d") and it will skip the spaces for you. It reads the groups of digits using the spaces as delimiter and reassembles the number for you to use it.

But if you want to read the file char by char then you can use fgetc() and you decide how to handle the spaces. For fgetc() a space is just a character like any other. The same for a digit. And it doesn't include any code to re-assemble the digits into numbers for you.

axiac
  • 68,258
  • 9
  • 99
  • 134
  • The disadvantages of this are that it doesn't insist on triplets of digits and it doesn't place the separate digits in the elements of `array`. It isn't clear how much of a problem that will actually be. – Jonathan Leffler Jul 24 '17 at 21:13