简单的minishell,由于fgets的工作方式,无法识别“退出”结束程序

时间:2014-02-09 16:13:28

标签: 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; 
}

它工作正常,但是当我输入“quit”时,程序不会结束。我想它必须与fgets相关,并且它在字符串str结尾处将EOF作为另一个字符包含在内,因此当我将它与“quit”进行比较时,它不是相同的字符串。 我不知道从标准输入中读取的字符串中提取\ n字符的正确方法。 ¿有人可以帮帮我吗?

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

4 个答案:

答案 0 :(得分:2)

  

我想它必须与fgets有关,并且它在字符串str结尾处将EOF作为另一个字符包含在内,因此当我将它与“quit”进行比较时,它不是相同的字符串。

不。

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

字符串中留下的fgets是换行符(如果由于它而停止,而不是因为EOF或错误)。您可以在获取字符串后轻松删除它 - 如果它存在 -

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

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

如果你写str != "quit",那么你在str"quit"之间进行指针比较,自str和{{} { 1}}是不同的字符数组,因此指向内存中的不同位置。你想要的是比较两个字符串的内容;在C中,用"quit"

完成
strcmp

答案 1 :(得分:2)

fgets也会在下面的语句中读取newline个字符。

fgets(str, LINE_LEN, stdin);

所以你有两个选择

  1. 使用以下条件来比较'退出':

    while (strcmp(str, "quit\n"))  
    
  2. 从输入中删除换行符。详情here

答案 2 :(得分:0)

您不能像执行str != "quit"

那样按指针比较字符串

改为使用0 != strcmp(str,"quit")

答案 3 :(得分:0)

if(str[4] == '\n')
    str[4] = '\0';
while (strcmp(str, "quit")!=0) {