Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 而Loop赢了';使用Read系统调用时无法退出_C_While Loop_System Calls - Fatal编程技术网

C 而Loop赢了';使用Read系统调用时无法退出

C 而Loop赢了';使用Read系统调用时无法退出,c,while-loop,system-calls,C,While Loop,System Calls,我正在使用linux系统调用构建一个充当shell的基本程序。现在我正试图让它以字符串的形式读取输入,这样我就可以根据需要修改信息。当我运行程序并从终端给它一些输入时,它会继续挂起。我猜我的while循环不会结束,但我不知道为什么。任何和所有的帮助都将不胜感激 #include <unistd.h> #include <stdlib.h> #include <stdio.h> int main(int argc, char ** argv) { in

我正在使用linux系统调用构建一个充当shell的基本程序。现在我正试图让它以字符串的形式读取输入,这样我就可以根据需要修改信息。当我运行程序并从终端给它一些输入时,它会继续挂起。我猜我的while循环不会结束,但我不知道为什么。任何和所有的帮助都将不胜感激

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

int main(int argc, char ** argv) {
    int i;

    char prompt[3] = "sh#";
    char input[256];
    char inputc;

    /*print out prompt */
    write(1, &prompt, sizeof(prompt));

    i = 0;
    while(read(0, &inputc, 1) != 0) {
        input[i] = inputc;
        i++;
    }
    input[i] = '\0';  /* null terminator */
    printf("%s\n", input);  

    return 0;
}
#包括
#包括
#包括
int main(int argc,字符**argv){
int i;
字符提示[3]=“sh#”;
字符输入[256];
字符输入UTC;
/*打印输出提示*/
写入(1,&prompt,sizeof(prompt));
i=0;
while(读取(0,&inputc,1)!=0){
输入[i]=inputc;
i++;
}
输入[i]='\0';/*空终止符*/
printf(“%s\n”,输入);
返回0;
}

您应该使用
getline()
而不是
read()
。因为
getline()
为您做了很多工作。另外,如果您只想从输入中接收一行,那么只需使用
read()
getline()
,而不使用您建立的
while()
循环。while循环对于多个输入是最必要的,这是我假设您想要的,因为您正在调用一个shell类型的程序,并且提示字符串中有
sh

如果您想在代码中使用
read()
,那么您应该创建自己的
getline()
,它使用
read()
。这可能是您自己使用
read()
为循环编写的
my_getline()
函数代码的一个示例,您应该根据自己的意愿添加中断条件

char *inputc, input[256];
int i;
for (i = 0; (read(STDIN_FILENO, inputc, 1) != EOF); i++)
{
    input[i] = inputc[0];
}
我已经用这个补丁修改了你的代码,并删除了不必要的变量。您没有使用
argc
**argv
,因此它们也被删除。while循环使用
getline()
而不是
read()
。字符串在每个输入行之后打印。当输入字符串为:
“quit”
时,迷你shell终止。如果您想在没有输入的情况下终止,您也可以为此添加修改

$ cat main.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
    size_t size = 256;
    char prompt[5] = "sh$ ";
    char *inputc = NULL;
    /* print out prompt */
    write(1, &prompt, 4);
    while(getline(&inputc, &size, stdin) != -1)
    {
        /* check if input is "quit" to terminate the mini shell */
        if (strncmp(inputc, "quit", 4) == 0)
            break;
        /* prints the input */
        printf("%s", inputc);
        /* re-print out prompt to continue loop*/
        write(1, &prompt, 4);
    }
    printf("%s\n", inputc);
    return 0;
}

您可能需要指定EOF字符。尝试输入您的输入,然后按ctrl-d。这应该很容易调试。当你将一个调试器连接到它并单步执行代码时,第二个while循环是否会爆发?@IharobAlAsimi知道你到底在键入什么吗?通过在大多数Linux系统上用Control-D指示EOF,可以告诉
read()
返回
0
,除非用
stty
更改该键。请注意,
read()
可以返回
-1
,但您的代码不会发现这一点,并且会进入尾部旋转,直到崩溃。因为你没有提到崩溃,所以有理由猜测你点击了“return”,但是你的程序没有发现换行符并退出循环;它只查找EOF(
read()
返回0)。您可以添加一个换行检查和
中断
。(如果您想通过一行输入部分指示EOF,请键入Control-D两次。)@Pablo:因为他没有使用
printf
,也没有将其视为字符串,
提示符
不需要以NUL结尾。实际上,将其设置为[4]会导致
write
调用同时写入NUL,这是不可取的。
$ gcc -Wall -Werror -Wextra -pedantic main.c
$ ./a.out 
sh$ This is a test
This is a test
sh$ See how well getline works!
See how well getline works!
sh$ 

sh$ quit
quit


$