【问题标题】:checking values of array using strcmp and nested loop使用 strcmp 和嵌套循环检查数组的值
【发布时间】:2013-02-20 07:01:25
【问题描述】:

我已经到了程序的最后一部分,我又遇到了一些问题。


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


问题 #2:我在调试时注意到了这一点。在我输入一个随机输入然后输入“历史”后,tokenArray 的第一个位置用“历史”填充,下一个位置用“历史”填充。为此,我不能使用嵌套循环和 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;
}

【问题讨论】:

  • 侧边栏:从不使用gets()。它是如此糟糕,它在 C99 中已被弃用,甚至在 C11 中也不存在。这很糟糕。请改用fgets() 和stdin。
  • 我有 fgets 但是我的程序没有做任何事情,没有退出,没有数组复制。这就是我使用gets() 的原因,我输入的所有内容都导致“找不到命令”。有什么想法吗?
  • 那确实很奇怪。我假设您使用了stdin 并为您的输入缓冲区提供了适当的长度。如果是这种情况,代码中还有另一个问题。我现在正在看。这是引起我注意的第一件事。
  • 是的,它看起来像这样fgets(inputString, 100, stdin);。好的,谢谢
  • 使用fgets() 时的问题是它保留行尾的换行符,而gets() 没有。通常你不想要它,所以你要么在比较时忽略它,要么先查找它并删除它。

标签: c arrays loops strcmp


【解决方案1】:

有几件事立即显而易见。

  1. 您永远不会将j 的值从一个命令行重置到下一个命令行。
  2. strtok() 不会仅仅因为您输入“命令”之类的内容而将单空格字符串添加到您的输入标记中。它会剥离 delims,所以你的逻辑在这个想法上是有缺陷的。 “command”的输入标记将是单个标记,对于“command one”,它将是“command”,并且只有“one”。您显然认为它会根据您对 strcmp(tokenArray[1], " " ) 所做的操作为您提供一个单空格字符串。
  3. 主要问题,但与您当前的问题无关,当k 变得足够大(准确地说是 100 个命令)时,您最终会超出堆栈
  4. 感谢@unwind,您需要丢弃使用fgets() 获取的换行符,这是我在测试时所做的。 Prolly 应该提到这一点。

修复第一个,重新考虑第二个,并考虑为第三个保存历史的替代结构。最后,我用fgets(inputString, 100, stdin); 对此进行了测试,它确实有效,所以不知道你那里出了什么问题。

【讨论】:

  • 我猜我有 #1。由于某种原因我不记得了。我对这部分问题的看法是这样的:将输入(“历史 1”)分成几部分。将第一部分插入tokenArray[j],将第二部分插入tokenArray[j+1]。然后检查:如果第一个是“历史”,检查第一个是否为空..等等是不是正确的?
  • 这似乎是一种更合乎逻辑的方法。我会试试的。谢谢你。编辑:你如何扔掉换行符?
  • @voth 只需找到字符串中的最后一个字符,如果它是 '\n' 字符,则将其设置为零 (0)。顺便说一句,在处理一个长度为 0 的字符串时要小心,从技术上讲你不应该这样做。
猜你喜欢
  • 2022-01-14
  • 2013-09-22
  • 2015-07-17
  • 1970-01-01
  • 2018-06-20
  • 2022-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多