在 Linux 的“C”中,我怎样才能中断 while() 循环,不知道中断是否或何时会发生 [closed]

In 'C', Linux, how can I interrupt a while() loop, not knowing if or when the interrupt will occur [closed]

提问人:gandsnut 提问时间:11/9/2023 更新时间:11/14/2023 访问量:86

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

14天前关闭。

我正在寻找一种方法来“中断”我的程序中的循环结构。 在 while(1) 循环中,有 STDIN 输入。仅当输入发生时, 循环是否继续。我一直在研究线程、信号和其他 实现此工作的可能方法。我不确定什么更合适。 该代码显示一个函数,用于检查文件是否存在。如果 发现,我希望对该事件做出进一步的决定。做 fscanf() 的阻塞性质使任何线程或信号方法无效?

#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>     //  for sleep()

int main(void);
int filefound(void);

int filefound()  {
    //  code to look for a file
    //  if found, return 'true'

    return(false);      //      file not found
    }

int main()    {
    char    instring[25];

    while (1)  {
        printf("\nType bad words:  ");

        fscanf(stdin, "%[^\n]%*c", instring);

        if (filefound() == true)
            printf("\nFILE FOUND\n");

        printf("\nPotty mouth...\n");
        sleep(3);
        }

    return(0);
    }

继续研究和试错。

C 循环 中断

评论

0赞 President James K. Polk 11/9/2023
那么,当你尝试使用信号时会发生什么?
1赞 0___________ 11/9/2023
说明您想要实现的目标。你的问题很清楚
0赞 Barmar 11/9/2023
您可以为 创建信号处理程序。然后,用户可以键入 Ctl-c 来中断循环。SIGINT
0赞 chux - Reinstate Monica 11/9/2023
@gandsnut、注意:风险溢出。最好是.fscanf(stdin, "%[^\n]%*c", instring);fscanf(stdin, "%24[^\n]%*c", instring);
0赞 chux - Reinstate Monica 11/9/2023
if (filefound() == true)很奇怪。最好是bool filefound(...) if (filefound())

答:

1赞 Gino V 11/9/2023 #1

你可以用几种方式停止 C 中的无限循环(或任何循环构造),从不那么激烈到更激烈:

跳出循环的语句

  1. continue;- 此语句实际上并不停止循环,而是停止当前迭代。当出于任何原因应跳过当前迭代时,它很有用。
  2. break;- 此语句本身将立即停止循环,并在循环结束后立即从该行继续。
  3. goto LABEL;- 这是你应该尽可能避免的。这是无条件地从你的代码跳到程序中的另一个地方。这通常被认为是不好的做法。但是,有一种情况仍然被认为是合适的选择,它打破了嵌套循环,而不是有一个可以设置的“退出标志”,然后打破了每个级别的循环。您可以在所有嵌套循环之后设置一个标签,然后在所有循环都应停止的任何条件下设置该标签。goto
  4. return;- 这个语句不仅会跳出循环,而且整个函数都会停止,之后放的任何值都会返回给调用者。这意味着 doing 将导致 假设 is 声明为int x = function()xfunction()function()int function()
  5. exit();- 这将结束程序。您需要包含 <stdlib.h> 才能使用它。

对于您的具体情况

在你的例子中,你可能希望在循环的某个地方有一行,可能是结尾,就像下面的第一个例子一样,但是,如果循环必须至少执行一次,你也可以更改条件本身或使用循环:do...while

最后休息:

#include <string.h>
...
while (1) {
    ...
    if (strncmp(strupr(instring), "EXIT") == 0) break;
}

更改条件

#include <string.h>
#include <stdlib.h>
#define LENGTH 25
...
char instring[LENGTH];
memset(instring, 0, LENGTH * sizeof(char));
...
while (strcmp(strupr(instring), "EXIT") != 0) {
    ...
}

使用 do-while 循环

#include <string.h>
#include <stdlib.h>
#define LENGTH 25
...
char instring[LENGTH];
memset(instring, 0, LENGTH * sizeof(char));
...
do {
    ...
} while (strcmp(strupr(instring), "EXIT") != 0)

其中任何一个都将以最佳方式完成您的要求。事实上,如果一旦优化,它们都会产生相同或几乎相同的机器代码,我不会感到惊讶。

解释

  • strcmp(const char * first, const char * second)比较两个字符串 - 和 - 并返回一个正数或负数,或零。当它返回零时,字符串是相同的。firstsecond
  • strupr(char * str)[1] 将字符串更改为大写,然后返回指向修改后的字符串的指针。str
  • memset(char * buffer, int value, size_t length)将指针中的内存字节设置为值 。在这种情况下,将所有 0 写入用于存储用户输入的数组。lengthbuffervalue

[1]:此功能仅适用于基于 Microsoft 的系统。因此,为了缓解这种情况,我包含了这个代码片段,如果你不在 Windows 上,你可以把它放在代码的顶部,以使用标准库函数来定义函数。

#if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
char * strupr(char * buffer) {
    for (int i = 0; true; i++) {
        if (buffer[i] == '\0') return buffer;
        buffer[i] = (char)toupper(buffer[i]);
    }
}
#endif

评论

0赞 Harith 11/9/2023
在哪里定义?它是Microsoft的扩展吗?strupr()
0赞 Adrian Mole 11/9/2023
@Harith 请参见:stackoverflow.com/q/26327812/10871073
0赞 Harith 11/9/2023
@AdrianMole Microsoft,正如预期的那样。谢谢。
0赞 Gino V 11/14/2023
好渔获!当我用谷歌搜索它时,我没有意识到这是微软特有的功能。我添加了一个代码片段,如果代码是在不存在代码的环境中编译的,您可以添加该代码来实现该函数。谢谢你们指出这一点,这样我就可以让我的答案更好。我希望它对任何有同样问题的人有所帮助。