Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
使用strcmp和嵌套循环检查数组值_C_Arrays_Loops_Strcmp - Fatal编程技术网

使用strcmp和嵌套循环检查数组值

使用strcmp和嵌套循环检查数组值,c,arrays,loops,strcmp,C,Arrays,Loops,Strcmp,我已经到了课程的最后一部分,我再次面临一些问题 问题#1:当我在标记化的while循环中打印数组的分隔字符串部分时,值是确定的。但是,当我打印put(tokenArray[1])时,只会显示命令的一个字母,例如:Input:“qwe rty”|在中打印,而循环:qwe rty |在循环外使用put(tokenArray[1])打印:“e”(是的,只显示字母) 问题2:我在调试时注意到了这一点。在我输入一个随机输入,然后输入“history”之后,tokenArray的第一个位置用“histo

我已经到了课程的最后一部分,我再次面临一些问题


问题#1:当我在标记化的while循环中打印数组的分隔字符串部分时,值是确定的。但是,当我打印
put(tokenArray[1])
时,只会显示命令的一个字母,例如:Input:“qwe rty”|在
中打印,而
循环:qwe rty |在循环外使用
put(tokenArray[1])
打印:“e”(是的,只显示字母)


问题2:我在调试时注意到了这一点。在我输入一个随机输入,然后输入“history”之后,
tokenArray
的第一个位置用“history”填充,下一个位置用“tory”填充。为此,我不能使用嵌套循环和strcmp,正如您在下面看到的,以检查第一部分是否为“历史”,如果是,则检查第二部分。如果第二部分为空,则仅显示命令的历史记录,或者如果为“1”/“2”等(当用户输入“历史记录1”时),则执行历史记录中的第一个命令

这是我目前的进展:

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

int main (int argc, char *argv[])
{
    int i=0; int j=0; int k=0;
    char inputString[100];
    char *result=NULL;
    //char *result2=NULL;
    char delims[] = " ";
    char historyArray[100][100] = {0};
    char historyKey[] = "history";
    char *tokenArray[100] = {0} ;
    //char exitString[] = "exit";

    do
    {
        printf("hshell>");
        gets(inputString);
        strcpy (historyArray[k], inputString);
        k++;

        // Break the string into parts
        result = strtok(inputString, delims);


        while (result!=NULL)
        {
            //result2 = result;
            tokenArray[j] = result;
            //puts(result);
            result= strtok(NULL, delims);
            //puts(tokenArray[j]);
            j++;
        }
        //j = 0;
        puts(tokenArray[1]);
        if (strcmp(tokenArray[0],historyKey) == 0)
        {
            if (strcmp(tokenArray[1], " " ) == 0)
            {
                for (i=0; i<k; i++)
                {
                    printf("%d. %s \n",i+1,historyArray[i]);
                }
            }
        }
        else if (strcmp ("exit",inputString) != 0)
        {
            printf("\nCommand not found \n");
        }

    } while (strcmp ("exit", inputString) != 0);
    return 0;
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
int i=0;int j=0;int k=0;
字符输入字符串[100];
char*result=NULL;
//char*result2=NULL;
char delims[]=“”;
字符历史数组[100][100]={0};
char historyKey[]=“历史记录”;
char*tokenArray[100]={0};
//char exitString[]=“退出”;
做
{
printf(“hshell>”);
获取(inputString);
strcpy(historyArray[k],inputString);
k++;
//把绳子断成几段
结果=strtok(输入字符串,delims);
while(结果!=NULL)
{
//结果2=结果;
tokenArray[j]=结果;
//放置(结果);
结果=strtok(空,delims);
//put(tokenArray[j]);
j++;
}
//j=0;
put(tokenArray[1]);
if(strcmp(tokenArray[0],historyKey)==0)
{
if(strcmp(令牌数组[1],“”)==0)
{

对于(i=0;i而言,有几件事情是显而易见的

  • 您永远不会将
    j
    的值从一个命令行重置到下一个命令行
  • strtok()
    不会仅仅因为您输入了“command”之类的内容就在输入令牌中添加一个空格字符串。它会去除delims,因此您的逻辑在这个想法上有缺陷。“command”的输入令牌将是一个令牌,“command one”的输入令牌将是“command”和“one”仅限。您显然认为它将从您使用strcmp(tokenArray[1],“”)所做的操作中为您提供一个空格字符串。
  • Major,但与您眼前的问题无关,当
    k
    变得足够大时(准确地说是100个命令),最终您将溢出堆栈
  • @unwind的功劳,你需要扔掉用
    fgets()
    获取的换行符,这是我在测试时做的。Prolly应该提到这一点

  • 修复第一个,重新考虑第二个,并考虑另一个用于保存第三的历史结构。最后,我用代码> fFET(输入字符串,100,STDIN)进行测试;,它确实有效,所以不知道你的结尾有什么错误。

    侧边栏:永远不要使用<代码> GETSH()。
    。它太糟糕了,从C99开始就被弃用了,甚至在C11中都没有出现。这太糟糕了。请改用
    stdin
    。我有
    fgets
    ,但我的程序什么都没做,没有退出,也没有数组复制。这就是为什么我使用
    gets()
    ,我键入的所有内容都会导致“Command not found”.有什么想法吗?那确实很奇怪。我想你使用了
    stdin
    ,并为输入缓冲区提供了适当的长度。如果是这样的话,代码中还有另一个问题。我现在正在查看。这是第一件引起我注意的事情。是的,它看起来像是
    fgets(inputString,100,stdin)
    。好的,谢谢使用
    fgets()
    时的问题是它将换行符保留在行尾,而
    获取()
    不需要。通常情况下,您不需要它,因此在比较时必须忽略它,或者首先查找并删除它。我想我已经#1。出于某种原因注释掉了,我不记得了。我对这部分问题的看法是:将输入(“历史记录1”)分解为多个部分。将第一部分插入
    tokenArray[j]
    令牌数组[j+1]
    中的第二个。然后检查:第一个是否为“历史记录”,检查first是否为空..等等,对吗?@voth1234如果我这样做,我会将标记拆分作为历史记录保存在一个结构中,并一次对其进行解析,与输入行并排。这似乎是一种更符合逻辑的方法。我会尝试。谢谢。编辑:如何抛出新行?@voth只需找到s中的最后一个字符tring并将其设置为零(0),如果它是'\n'字符。顺便说一句,在处理长度为0的字符串时要小心,这在技术上是不应该的。