c - 仅通过 EOF 结束 while 循环一次

标签 c loops while-loop scanf eof

我正在尝试解决这个问题,但不幸的是我找不到任何解决方案。

我有一个循环,我想用 EOF 来打破它,但它总是需要它两次而不是一次。

    do {
        int input = scanf("%d", &elements[count++]);
        if (input == EOF) {
            break;
        }
        if (input == 0) {
            wrongInput = true;
            return;
        }
    } while (1);

我也这样尝试过,但也没成功:

    while ((int input = scanf("%d", &elements[count++])) != EOF) {
        if (input == 0) {
            wrongInput = true;
            return;
        }
    }

我总是必须按 Ctrl-D 两次。这是整个代码:

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

int count = 0;

int elements[1000000];

int diff = 0;
int optCount = 0;
int firstElement[1000000];
int secondElement[1000000];

bool wrongInput = false;

void inputArr() {

    bool emptyCheck = false;
    // Perform a do-while loop

    do {
        int input = scanf("%d", &elements[count++]);
        if (input == EOF) {
            break;
        }
        if (input == 0) {
            wrongInput = true;
            return;
        }
        if (input != 1) {
            emptyCheck = true;
        }
    } while (1);

    // Resize the array size to count
    elements[count];
    if (emptyCheck == true) {
        elements[count--];
    }
}

void farthestMax(int b[], int n) {
    // To store maximum element in the range i to n
    int suffix_max[n];
    suffix_max[n - 1] = b[n - 1];
    for (int i = n - 2; i >= 0; i--)
    {
        suffix_max[i] = (suffix_max[i + 1] > b[i]) ? suffix_max[i + 1] : b[i];
    }

    for (int i = 0; i < n; i++)
    {
        int low = i + 1, high = n - 1, ans = -1;

        while (low <= high)
        {
            int mid = (low + high) / 2;

            // If current element in the suffix_max is greater than b[i] then move right
            if (suffix_max[mid] > b[i])
            {
                ans = mid;
                low = mid + 1;
            }
            else
                high = mid - 1;
        }

        // Print the required answer
        int currentDiff = ans - i;
        if (ans != -1) {
            if (currentDiff == diff) {
                firstElement[optCount] = i;
                secondElement[optCount] = ans;

                optCount++;
            }
            if (currentDiff > diff) {
                diff = currentDiff;
                optCount = 1;
                firstElement[0] = i;
                secondElement[0] = ans;
            }
        }
    }
}

int main() {
    printf("Input numbers:\n");
    inputArr();
    if (wrongInput == true) {
        printf("Wrong input.\n");
        return EXIT_FAILURE;
    }
    printf("\n");
    farthestMax(elements, count);
    if (optCount == 0) {
        printf("Cant find.\n");
    } else {
        for (int i = optCount - 1; i >= 0; i--) {
            printf("%d: %d - %d\n", diff + 1, firstElement[i], secondElement[i]);
        }
        printf("Options: %d\n", optCount);
    }

    return EXIT_SUCCESS;
}

最佳答案

您观察到的行为是默认情况下与 EOF 终端函数关联的特殊字符 Ctrl-D 的终端处理的副作用,如 中所述>termios 手册页:

     EOF     Special character on input and is recognized if the ICANON flag
             is set.  When received, all the bytes waiting to be read are 
             immediately passed to the process, without waiting for a
             newline, and the EOF is discarded.  Thus, if there are no bytes
             waiting (that is, the EOF occurred at the beginning of a line),
             a byte count of zero is returned from the read(), representing
             an end-of-file indication.  If ICANON is set, the EOF character
             is discarded when processed.  NL Special character on input and 
             is recognized if the ICANON flag is set.  It is the line
             delimiter `\n'.

当您在循环中使用 scanf("%d", ...) 读取输入时,scanf 函数会读取字符,跳过初始空格并将数字,直到从终端获得非数字输入或文件末尾。默认情况下,终端是行缓冲的,因此当用户按 Enter 或在某些特殊情况下,用户输入将刷新到调用者。如果在非空行末尾键入 Ctrl-D,则该行内容将刷新到进程。在这种情况下,scanf 最终将尝试并继续从标准输入读取,因为短读取计数不被视为结束 iof 文件,而如果您在在空行的开头,或者在刷新之后,来自终端的读取请求将返回0,流读取函数将其解释为文件结尾。

因此,如果您不在行首,则可能需要键入 Ctrl-D 两次。

关于c - 仅通过 EOF 结束 while 循环一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77512176/

相关文章:

c - C 字符串中 ptr、ptr[0] 和 &ptr[0] 的区别

c - 许多无效的符号索引和对 main 的 undefined reference

c - 用FD_SET制作读写集,用于在C中发送和接收数据

c - 我怎样才能阻止程序读取 'Enter' 作为输入?

java - 嵌套While循环逻辑错误

java - 如何退出 switch 语句并返回到 While 循环?

c++ - 如何用c/c++最方便的处理jpg图片?

c - 如何使用fscanf()获取多种格式的字符串?

javascript - Jquery 的 JSON 递归循环问题

python-3.x - 循环将多个列表附加到数据帧python中