0

Here is the logic what I am trying to do;

  • get input char with fgetc() in the variable named ch,
  • check if not ch is EOF or equal to '\n',
  • increase int variable named counter,
  • then put the variable ch to stdin using ungetc()
  • repeat process

After that, allocate the memory with counter. Again, get char in stdin, using fgetc() and store it into array.

This thought is working with only one char input. This is the code I wrote for two or more inputs;

while ( ((entry = fgetc(stdin)) != EOF) && (entry != '\n'))
    {
        ++counter;
        ungetc(entry, stdin);
        fprintf(stdout, "%c,%d ", entry, counter); // 
    } //;

This is the output of console when I enter qwert as an input;

q,2 q,3 q,4 q,5 q,6 q,7 q,8 q,9 q,10 q,11 q,12 q,13 q,14 q,15 q,16 q,17 q,18 q,19 q,20 q,21 q,22 q,23 q,24 q,25 q,26 q,27 q,28 q,29 q,30 q,31 q,32 q,33 q,34 q,35 q,36 q,37 q,38 q,39 q,40 q,41 q,42 

After read first char it keeps reading first character never gets second or others.

Os : Windows 10 | MinGW gcc-9.1.0

What am I doing wrong? Is it even possible?

kek
  • 23
  • 4
  • 1
    this is not a feasable approach, however you can use realloc to keep increasing your buffer. – Ahmed Masud Dec 01 '21 at 20:02
  • 3
    The `ungetc()` function makes the ungotten character available for the next read, so you have an infinite loop, as you discovered. You don't need to use `ungetc()`. As long as the input stream is a regular file, you'll be able to `rewind()` at the end (or use `fseek()`) and reread the data. If the input stream is not a regular file, you can't reread the data — period. So, the safest course of action is to allocate space upfront, keeping track of the size allocated and the space used and reallocating more space when necessary. – Jonathan Leffler Dec 01 '21 at 20:07
  • Note that the empty statement after the end of the loop `};` is pointless. Don't put semicolons there. – Jonathan Leffler Dec 01 '21 at 20:08
  • 4
    `ungetc` only guarantees a single character's worth of read/pushback — not the whole line's worth you'd need for this to work. I believe that `realloc` is the best way to handle this. Or the Posix [`getline`](https://linux.die.net/man/3/getline) function will take care of it for you. – Steve Summit Dec 01 '21 at 20:25
  • I didn't want to use 'realloc' because it could be point different address. I want to avoid assign all character again and again. – kek Dec 01 '21 at 20:47
  • 1
    Don't worry, `realloc` is often able to grow the array in-placce, meaning that already-read characters won't often have to be moved. You can minimize that chance by picking a big initial allocation. – Steve Summit Dec 01 '21 at 20:56
  • 1
    You can always use `rewind()` or `fseek()` if you mind using `realloc()`. – alex01011 Dec 01 '21 at 21:12
  • 1
    `fileno()` + `stat()`. Note that if standard input is a pipe, you can't tell the size ahead of time. – Shawn Dec 01 '21 at 22:17
  • 1
    @Shawn Standard input can also be a tty or socket, which also don't have a known size. – Andrew Henle Dec 01 '21 at 23:10
  • 1
    @alex01011 *You can always use `rewind()` or `fseek()`...* No you can't. As noted in the above two comments, neither streams nor file descriptors have to be seekable or even have any concept of a "size" at all. – Andrew Henle Dec 01 '21 at 23:12
  • 2
    @kek *I didn't want to use 'realloc' because it could be point different address. I want to avoid assign all character again and again.* That's not a bad approach - minimize work done. But in this case, there's no general way to do that because there's no way you can be sure about how many bytes you're going to read. The input might not have a size, and even if it does, depending on the value you read is a [TOCTOU bug](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use). What if the file changes size after you check it? – Andrew Henle Dec 01 '21 at 23:15
  • I did it with different approach. I allocated huge chunk of memory. For example, 1MB memory. if I enter 'qwert', it writes to allocated pointer and reallocated it with counter and shrinks it with that size. Technically it will always return same address and other spaces after freed with realloc can be use other processes. Is it good approach? @AndrewHenle – kek Dec 02 '21 at 21:02

0 Answers0