使用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的字符串时要小心,这在技术上是不应该的。