c - 简单的 minishell,由于 fgets 的工作方式,无法识别 "quit"以结束程序

标签 c token fgets fflush

我正在尝试用这段代码编写一个 minishell:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_LEN  50
#define MAX_PARTS  50

int main ()
{
char* token;
char str[LINE_LEN];
char* arr[MAX_PARTS];
int i,j;

printf("Write a line: \n $:");
fgets(str, LINE_LEN, stdin);

while (str != "quit") {
    i=0;
    token = strtok(str, " \t\r\n");
    while( token != NULL ) 
    {
        arr[i] = token;
        printf("'%s'\n", arr[i]);
        i++;
        token = strtok(NULL," \t\r\n");
    }
    fflush(stdin);

    printf("Write a line: \n $:");
    fgets(str, LINE_LEN, stdin);
}   
return 0; 
}

它工作正常,但事实上当我输入“退出”时,程序并没有结束。我想它一定与 fgets 以及它在字符串 str 的末尾将 EOF 作为另一个字符结合在一起这一事实有关,因此当我将它与“quit”进行比较时,它不是同一个字符串。 我不知道从标准输入读取的字符串中提取\n 字符的正确方法是什么。 ¿有人能帮帮我吗?

我想问的另一个问题是在此代码中使用 fflush 是否是个好主意。 谢谢

最佳答案

I guess it must be related with fgets and the fact that it incorporates EOF as another character at the end of string str, so when I compare it with "quit" it's not the same string.

没有。

首先,EOF不作为字符存在,它只是一些 IO 函数返回的标志,告诉您文件在尝试读取时已完成。

什么 fgets字符串中的 leaves 是换行符(如果它因为它而不是因为 EOF 或错误而停止)。您可以在获取字符串后轻松删除它(如果存在):

size_t l=strlen(str);
if(l && str[l-1]=='\n')
    str[l-1]=0;

但最重要的是,您正在与 "quit" 进行比较错误的。

如果你写str != "quit"您正在执行 str 之间的指针 比较和 "quit" , 自 str 以来总是会失败和 "quit"是不同的字符数组,因此指的是内存中的不同位置。你想要的是比较两个字符串的内容;在 C 中,这是用 strcmp 完成的:

while(strcmp(str, "quit")!=0)

关于c - 简单的 minishell,由于 fgets 的工作方式,无法识别 "quit"以结束程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21661494/

相关文章:

c - 我想问一下我失败的代码

C取消引用指针警告,甚至认为它们都是字符

ruby-on-rails-3 - Devise 中的 token 可验证模块

javascript - Node Express 处理来自外部 api 的身份验证 token

c - 从 stdin 向 fgets 发送任意字节

c - 程序跳过用户输入的机会,使用 fgets 和 sscanf

c++ - VS2013添加DLL项目

C 编译器中的列优先数组存储

c - 使用 C 删除尾随空格后,字符串为空

java - 如何从输入中读取并报告两个字符串在完全相同的位置是否具有完全相同的 'tokens' ?