0

I need to read a matrix of variable order from stdin. The first line of the input is the order (N) of the matrix and the following N lines all should have N space separated integers. However, lines are allowed to have comments after all needed input for that line was sent.

As an example, this is 100% valid input:

3        Matrix Order
1 2 3    Line 0
4 5 6    Line 1
7 8 9    Line 2
/empty line

I've managed to do that using the following code:

scanf("%d", &matrixOrder);
scanf("%*[^\n]");

for (i = 0; i < matrixOrder; i++) {
    for (j = 0; j < matrixOrder; j++) {
        scanf("%d", &matrix[i][j]);
    }

    scanf("%*[^\n]");
}

However, I must also be able to know when the line does not provide all the needed input and output a warning message. For instance, the following example should output a warning:

3
1 1 1
1 1 1
1 1
/empty line

My current code simply ignores the missing entry.

The only way I could think of possibly doing this would be to read a single character at a time and, once reaching a new line character, checking if I had already received all the input I needed for that line. That, however would require me to read the integers, which may have multiple digits and even negative values, as characters and do the conversion myself. That seems to be far from a ideal solution to me.

Is there any better, intelligent way of doing this? I ask mainly because I don't come from a C background and am not really used to it yet.

rmobis
  • 26,129
  • 8
  • 64
  • 65
  • 2
    Read the lines with `fgets()`, then process the line contents with `sscanf()`. Then you don't even need to do anything to skip the comments. – Barmar Sep 04 '14 at 02:53
  • What background do you come from? How would you have done it in that language? I suspect it's similar to what I just wrote. Most languages aren't really that different, it's just syntax. – Barmar Sep 04 '14 at 02:54
  • @Barmar The problem with `fgets` is that if the input line is too long (e.g. from a long comment), the unread portion of it will be left behind (and undesirably picked up by the next call to `fgets`). – jamesdlin Sep 04 '14 at 03:21
  • @Barmar, basically PHP and scripting (Lua, JS). If I were to do it in any of those languages, I would probably read all the input and try to match it afterwards, as you suggested. The problem is, in those languages I don't need to worry about a maximum size for the line, the language takes care of it for me. And because I simply cannot make any assumption on its maximum size, this solution wouldn't be ideal for me. – rmobis Sep 04 '14 at 03:21
  • http://stackoverflow.com/a/3302594/179715 – jamesdlin Sep 04 '14 at 03:32
  • I see, @jamesdlin. However, as I pointed, `fgets` really would be a pain to use in this case because I have absolutely no guarantee on the maximum length of the line. Because I'm not using the `%s` format, and the input format shouldn't vary that much, is using `scanf` okey for this situation, in your opinion? – rmobis Sep 04 '14 at 03:45
  • @Raphael_ Dealing with missing input will be tricky with `scanf`. For example, consider what if you omitted an element from a row in the middle of your matrix. – jamesdlin Sep 04 '14 at 04:14

1 Answers1

2

You can check the return value of scanf and print the necessary warning message:

if ( scanf("%d", &matrix[i][j]) != 1 )
{
   printf("Warning: did not find a number for row=%d and col=%d\n", i, j);
}

The loop can be:

for (i = 0; i < matrixOrder; i++) {
  for (j = 0; j < matrixOrder; j++) {
     if ( scanf("%d", &matrix[i][j]) != 1 )
     {
        printf("Warning: did not find a number for row=%d and col=%d\n", i, j);
        break;
     }
  }
  scanf("%*[^\n]");
}
rmobis
  • 26,129
  • 8
  • 64
  • 65
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thanks, that's exactly what I needed. I wasn't really aware of `scanf`'s return value. – rmobis Sep 04 '14 at 03:28
  • 2
    I don't see how this will generate a warning if a row has insufficient elements. `scanf` treats all whitespace the same and doesn't care about newlines. Won't it print the warning only if `scanf` receives input that can't be parsed as an `int`? – jamesdlin Sep 04 '14 at 04:18
  • @jamesdlin, good observation. It will print warning only if `scanf` receive input that can't be parsed as an `int` or EOF has reached. – R Sahu Sep 04 '14 at 04:29
  • @jamesdlin, because I receive all the input at once (it's actually piped through a file), EOF is always reached. – rmobis Sep 05 '14 at 23:56
  • @Raphael_ Even if all if the input is piped through a file, you won't get appropriate warnings if, say, an elements are missing from rows in the middle. For example, if you intend to input a matrix with 5 rows and 3 columns, but 1 element is missing from 3 of the rows, I believe you'd silently end up with a 4x3 matrix... – jamesdlin Sep 06 '14 at 01:34
  • @jamesdlin, It doesn't because it reaches end of file and when it happens, `scanf` fails. The only thing I can't handle right now is that it doesn't fail if you have like, a 3x3 matrix and you pass 9 lines with a single int each. – rmobis Sep 06 '14 at 03:31