我正在尝试解决这个问题,但不幸的是我找不到任何解决方案。
我有一个循环,我想用
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;
}
您观察到的行为是特殊字符 Ctrl-D 的终端处理的副作用,默认情况下与
EOF
终端功能相关联,如 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
函数会读取字符,跳过初始空格并转换数字,直到从终端获取非数字输入(默认情况下是行缓冲的)。如果您在非空行末尾键入 Ctrl-D,该行内容将刷新到进程,并且 scanf
最终将尝试继续从标准输入读取,而如果您在空行的开头,或者刷新之后,来自终端的读取请求将返回 0
,流读取函数将其解释为文件结尾。因此,如果您不在行首,则可能需要输入 Ctrl-D两次。