-4

Comment on the output of this C code:

#include <stdio.h>
int main()
{
  char c;
  int i = 0;
  FILE *file;
  file = fopen("test.txt", "w+");
  fprintf(file, "%c", 'a');
  fprintf(file, "%c", -1);
  fprintf(file, "%c", 'b');
  fclose(file);
  file = fopen("test.txt", "r");
  while ((c = fgetc(file)) !=  -1)
      printf("%c", c);
  return 0;
}

a) a

b) Infinite loop

c) Depends on what fgetc returns

d) Depends on the compiler

Answer: a

Explanation: None.

Why is the answer a?

I think it may result from the answer from the statement: “fprintf(file,"%c",-1)”. After the error occurs, why didn't the program output b?

Golden Fish
  • 81
  • 1
  • 9
  • 3
    I doubt you'll get an answer to your question. This is obviously homework that you are asking us to do for you. You can easily find the answer to your question by inserting `printf()` statements at each step to know exactly what is going on with your code. – Swifty Jan 07 '18 at 08:05
  • Welcome to Stack Overflow! Check how to create How to [create a Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example so that you can get a much better response to your question. – n4m31ess_c0d3r Jan 07 '18 at 08:10
  • https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ and https://meta.stackoverflow.com/questions/334822/how-do-i-ask-and-answer-homework-questions might be interesting reads for you. – Yunnosch Jan 07 '18 at 08:30
  • 2
    Think about whether `(char)-1` is a valid value, and why `fgetc` returns an `int` instead of a `char`. – Ry- Jan 07 '18 at 08:33
  • the return value of [getchar must be stored into an int](https://stackoverflow.com/questions/35356322/difference-between-int-and-char-in-getchar-fgetc-and-putchar-fputc) – Antti Haapala -- Слава Україні Jan 07 '18 at 08:48
  • No error occurred. You may want to look at `test.txt` in a hex editor. – melpomene Jan 07 '18 at 09:01
  • thx you guys a lot. i know that getchar(-1) means EOF... – Golden Fish Jan 07 '18 at 09:13
  • The "trick question" with `EOF` is that `int(-1)` might not be the same as `char(-1)`. And that's the lesson to learn here. – Bo Persson Jan 07 '18 at 11:19
  • @RX9: (a) It looks more like a returned quiz question (question is given, answer is given, student wants to know why answer is what it is) than a homework assignment (homework rarely asks why the answer of a multiple choice question is what it is). (b) Asking about homework is okay. (c) Inserting `printf` shows what **one** C implementation does; it does not definitively answer whether behavior depends on the compiler. – Eric Postpischil Jan 07 '18 at 11:47
  • @RX9: Furthermore, if it is a homework assignment, it is wrong, and so it is worthy of discussion and correction. – Eric Postpischil Jan 07 '18 at 12:02
  • @EricPostpischil Not sure I would agree with you about (a). The assumption that the answer is given can't be proven. The assignment question may very well have been the following: "*What is the output of the following code? Explain.*" The student may have run the code on his/her machine and then found out what the output is but now he/she can't find a justification for said output. (b) Asking homework is okay as long as OP has shown effort into solving it. I can't see any effort from their part aside from the "guess" that the error is due to a particular print statement – Swifty Jan 07 '18 at 12:11
  • which isn't telling about the effort put into solving the question before asking us. Anyway, the downvotes on this question and the fact it was put on hold is a pretty obvious indication about what the community thinks about the validity of this question. – Swifty Jan 07 '18 at 12:16
  • @RX9: No, every mainstream compiler will not interpret these statements in the same way. The C standard is incomplete; there is considerable behavior of C source code that is not defined, some of which implementations are required to define and some of which they are not. As my answer shows, implementations that differ in the signedness of `char` will differ in their results. – Eric Postpischil Jan 07 '18 at 12:18
  • Oh, I understand what you mean. I edited that part out of my previous comment – Swifty Jan 07 '18 at 12:20

1 Answers1

1

Technically, the answer is (d), depends on the compiler. This is because char may be unsigned, in which case c = fgetc(file) will never evaluate to -1. Conversely, char may be signed, in which case c = fgetc(file) may evaluate to -1.

The result of an assignment is the value assigned to the left side (which is not the value of the right side but rather the value of the right side converted to the type of the left side). Thus, if char is unsigned, then c = fgetc(file) always has some value of an unsigned char, so it is never negative and can never be -1. The program then loops forever.

If char is signed, then, in normal conditions, the second fgetc(file) evaluation returns the character that was written to the file when -1 was written. Note that, for %c, fprintf converts its int argument to unsigned char (even if char is signed) and writes that. Thus, writing -1 results in writing UCHAR_MAX to the file. Similarly, fgetc returns an unsigned char converted to an int. Thus, in c = fgetc(file), we have the signed char being assigned the value UCHAR_MAX (typically 255). For assignment, this value is converted to signed char. When a value being converted does not fit in the new type, there is either an implementation-defined result or an implementation-defined signal. If the implementation produces -1, then the program normally stops after printing “a”. If the implementation raises a signal, it will be handled, typically by terminating the program. If the implementation neither signals nor produces -1, the program will continue by printing the resulting character and then printing “b”. After that, fgetc will normally return EOF. If the result of converting EOF to char is -1, then program will then stop. Otherwise, it will either raise a signal or continue printing the result of converting EOF to char indefinitely.

(Note: The question alludes to an error caused in or by fprintf. In normal circumstances, there is no error in fprintf(file, "%c", -1). For this call, fprintf writes the result of converting -1 to an unsigned char to the file.)

Additionally, we must consider that fopen could fail (e.g., due to permissions), fclose could fail (e.g., due to available disk space or a device error), and fopen could fail (e.g., due to another process removing the file between the fclose and the fopen). So none of the answers is complete.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312