0

I am really desperate trying to figure out how can I read char with value -1/255 because for most functions this means EOF. For example if I enter all characters from extended ASCII from low to high (decimal value) I end up with -1/255 which is EOF so I will not get it to array. I created small code to express my problem.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUFFERSIZE 1024

int main(void){
char c;
unsigned int *array = (unsigned int*)calloc(BUFFERSIZE,sizeof(unsigned int)), i = 0;
while (1){
    c = fgetc(stdin);
    if (c == EOF)
        break;
    array[i] = c;
    i++;
}
array[i] = 0;
unsigned char *string = (unsigned char *)malloc(i);
for(int j = 0;j < i;j++)
   string[j] = array[j];
free(array);

//working with "string"

return 0;
}

I could mode

if (c == EOF)
   break; 

like this

c = fgetc(stdin);
array[i] = c;
i++;
if (c == EOF)
   break;

but ofcourse, program will read control character that user input from keyboard too (for example Ctrl+D - Linux). I tried opening stdin as binary but I found out that posix systems carries all files as binary. I am using QT, GCC and Ubuntu. I tried fread, read, fgets but I ended up the same. Simply said, I need to read everything I enter on stdin and put it into char array except when I enter control character (Ctrl+D) to end reading. Any advices appreciated.

Peter
  • 449
  • 1
  • 3
  • 13
  • `negative 1` would be `2` characters, do you want `negative 1` as an `int`? – Jared Burrows Apr 26 '15 at 00:00
  • Could you explain to me why you do `while (1) { c = fgetc(stdin); if (c == EOF) break;}` instead of `while ((c = fgetc(stdin)) != EOF)` I just keep seeing that and I am really unable to understand who teaches such a weird and unecessary thing. – Iharob Al Asimi Apr 26 '15 at 00:00
  • 8
    fgetc() returns an INT, not a char... change "char c;" to "int c;" and it should work. – TonyB Apr 26 '15 at 00:04
  • If I am not mistaken all control characters consist of a ^ and then a uppercase letter, so a solution might be to check if array[i] == '^' then if the next character is a uppercase letter, the user has entered a control character. – Reds Apr 26 '15 at 00:05
  • @Peter Note that you are evaluating two conditions instead of one, so I would really love to know where does that come from. Because it's not only ugly but not as efficient as the simple and evident version. – Iharob Al Asimi Apr 26 '15 at 00:07
  • Can believe I have not seen this. Thanks. – Peter Apr 26 '15 at 01:05
  • @Reds ^X is just a representation that is useful when you're a terminal that is printing/echoing them. Actual characters have codes 00-1Fh (also 7F). They are represented with ^letters from 1. For example: ^I is a tab (code 09h, latin letter #9), ^D is [E]nd [O]f [T]ransmission (code 03h, latin letter #3). ^M is CR. You can shift first two rows of this table 4 times down and see why ^[ maps to escape: http://upload.wikimedia.org/wikipedia/commons/4/4f/ASCII_Code_Chart.svg – user3125367 Apr 26 '15 at 01:27
  • `array[i] = 0; unsigned char *string = (unsigned char *)malloc(i);` --> `array[i++] = 0; unsigned char *string = malloc(i);` (increment `i`). – chux - Reinstate Monica Apr 26 '15 at 04:46
  • 1
    `fgetc(stdin)` returns an `int` with the values in the range of `unsigned char` (typically 256 different values) and `EOF` (some negative number). So after insuring the return value if not `EOF`, then code may continue on and use `array[i] = c` – chux - Reinstate Monica Apr 26 '15 at 05:00

1 Answers1

2

Edit: As noted in the comment by @TonyB you should not declare c as char because fgetc() returns int, so changing it to int c; should make it possible to store EOF in c.

I didn't see that you declared c as char c; so all the credit goes to @TonyB.

Original Answer: Although the problem was addressed in the comments, and I added the solution to this answer, I think you are confused, EOF is not a character, it's a special value returned by some I/O functions to indicate the end of an stream.

You should never assume that it's vaule is -1, it often is but there is a macro for a reason, so you should always rely on the fact that these functions return EOF not -1.

Since there is no ascii representation for the value -1 you can't input that as a character, you can however parse the input string {'-', '1', '\0'}, and convert it to a number if you need to.

Also, Do not cast the return value of malloc().

Community
  • 1
  • 1
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97