提问人:gandsnut 提问时间:11/9/2023 更新时间:11/14/2023 访问量:86
在 Linux 的“C”中,我怎样才能中断 while() 循环,不知道中断是否或何时会发生 [closed]
In 'C', Linux, how can I interrupt a while() loop, not knowing if or when the interrupt will occur [closed]
问:
我正在寻找一种方法来“中断”我的程序中的循环结构。 在 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);
}
继续研究和试错。
答:
1赞
Gino V
11/9/2023
#1
你可以用几种方式停止 C 中的无限循环(或任何循环构造),从不那么激烈到更激烈:
跳出循环的语句
continue;
- 此语句实际上并不停止循环,而是停止当前迭代。当出于任何原因应跳过当前迭代时,它很有用。break;
- 此语句本身将立即停止循环,并在循环结束后立即从该行继续。goto LABEL;
- 这是你应该尽可能避免的。这是无条件地从你的代码跳到程序中的另一个地方。这通常被认为是不好的做法。但是,有一种情况仍然被认为是合适的选择,它打破了嵌套循环,而不是有一个可以设置的“退出标志”,然后打破了每个级别的循环。您可以在所有嵌套循环之后设置一个标签,然后在所有循环都应停止的任何条件下设置该标签。goto
return;
- 这个语句不仅会跳出循环,而且整个函数都会停止,之后放的任何值都会返回给调用者。这意味着 doing 将导致 假设 is 声明为int x = function()
x
function()
function()
int function()
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)
比较两个字符串 - 和 - 并返回一个正数或负数,或零。当它返回零时,字符串是相同的。first
second
strupr(char * str)
[1] 将字符串更改为大写,然后返回指向修改后的字符串的指针。str
memset(char * buffer, int value, size_t length)
将指针中的内存字节设置为值 。在这种情况下,将所有 0 写入用于存储用户输入的数组。length
buffer
value
[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
好渔获!当我用谷歌搜索它时,我没有意识到这是微软特有的功能。我添加了一个代码片段,如果代码是在不存在代码的环境中编译的,您可以添加该代码来实现该函数。谢谢你们指出这一点,这样我就可以让我的答案更好。我希望它对任何有同样问题的人有所帮助。
评论
SIGINT
fscanf(stdin, "%[^\n]%*c", instring);
fscanf(stdin, "%24[^\n]%*c", instring);
if (filefound() == true)
很奇怪。最好是bool filefound(...) if (filefound())