这似乎是一个非常简单的问题,但我正在努力解决它。我已经用Objective C编写了iPhone应用程序几个月了,但是我决定学习C编程以给自己一个更好的基础。
在Objective-C中,如果我有一个名为'label1'的UILabel,其中包含一些文本,我想根据该文本运行一些指令,那么它可能就像是;
if (label1.text == @"Hello, World!")
{
NSLog(@"This statement is true");
}
else {
NSLog(@"Uh Oh, an error has occurred");
}
我编写了一个非常简单的C程序,我编写了一个使用printf()
来请求输入然后使用scanf()
来接受用户的一些输入,所以像这样的东西;
int main()
{
char[3] decision;
Printf("Hi, welcome to the introduction program. Are you ready to answer some questions? (Answer yes or no)");
scanf("%s", &decision);
}
我想要做的是应用if
语句来说明用户是否输入了是,然后继续提出更多问题,否则打印出一行文字说谢谢。
使用scanf()函数后,我捕获用户输入并将其分配给变量'decision',这样现在应该等于yes或no。所以我以为我可以做这样的事情;
if (decision == yes)
{
printf("Ok, let's continue with the questions");
}
else
{
printf("Ok, thank you for your time. Have a nice day.");
}
这会出现“使用未声明的标识符是”的错误。我也试过了;
if (decision == "yes")
带来“与字符串文字的比较结果未指定”
我已经尝试通过计算已放置的字符数来查看它是否有效;
if (decision > 3)
但是得到“指针与整数之间的有序比较'Char和int'”
我也试过这个来检查变量的大小,如果它大于2个字符则必须是;
if (sizeof (decision > 2))
我很欣赏这可能是我所忽视的简单或微不足道的事情,但任何帮助都会很棒,谢谢。
答案 0 :(得分:4)
Daniel Haviv的回答告诉你应该做什么。我想解释为什么你尝试的东西不起作用:
if (decision == yes)
没有标识符'是',所以这不合法。
if (decision == "yes")
这里,“yes”是一个字符串文字,它的计算结果是指向第一个字符的指针。这将“决定”与等效指针进行比较。如果它是合法的,如果它们都指向同一个地方,那就不是你想要的那样。事实上,如果你这样做:
if ("yes" == "yes")
行为未定义。如果实现将相同的字符串文字折叠到相同的内存位置,它们将指向相同的位置,它可能会也可能不会。所以肯定不是你想要的。
if (sizeof (decision > 2))
我认为你的意思是:
if( sizeof(decision) > 2 )
'sizeof'运算符在编译时评估,而不是运行时。它独立于存储的内容。 sizeof决定是3,因为您将其定义为包含三个字符。所以这不会测试任何有用的东西。
如在另一个答案中所提到的,C有'strcmp'运算符来比较两个字符串。如果您愿意,您也可以编写自己的代码来逐个字符地进行比较。 C ++有更好的方法,包括字符串类。
以下是您可能会如何做到这一点的示例:
int StringCompare(const char *s1, const char *s2)
{ // returns 0 if the strings are equivalent, 1 if they're not
while( (*s1!=0) && (*s2!=0) )
{ // loop until either string runs out
if(*s1!=*s2) return 1; // check if they match
s1++; // skip to next character
s2++;
}
if( (*s1==0) && (*s2==0) ) // did both strings run out at the same length?
return 0;
return 1; // one is longer than the other
}
答案 1 :(得分:2)
您应该使用strcmp
:
if(strcmp(decision, "yes") == 0)
{
/* ... */
}
答案 2 :(得分:2)
要进行比较,您可以像这样使用strcmp
:
if(strcmp(decision,"yes") == 0) {
// decision is equal to 'yes'
}
此外,您应该将char decision[3]
更改为char decision[4]
,以便缓冲区具有
终止空字符的空间。
char decision[4] = {0,0,0,0}; // initialize to 0
答案 3 :(得分:2)
好的一些事情:
decision
需要是一个包含4个char
的数组,以便在其中包含字符串“yes”。那是因为在C中,字符串的结尾由NUL char
('\0'
)表示。因此,您的char
数组将如下所示:{ 'y', 'e', 's', '\0' }
。strcmp
等函数比较char
数组)的内容,而不是<强>位置强> /指针。返回值0表示两个字符串匹配。scanf("%s", &decision);
,您不需要使用address-of运算符,数组的标签是数组开头的地址。strlen
来获取字符串的长度,这只会增加一个计数器,直到它到达NUL char
,'\0'
。您不使用sizeof
来检查字符串的长度,这是一个编译时操作,它将为3 * sizeof(char)
返回值char[3]
。scanf
不安全要与字符串一起使用,您应该使用fgets(stdin...)
,或在格式字符串中包含宽度说明符(例如"3%s"
)为了防止溢出缓冲区。 注意如果您使用fgets
,请考虑如果新行char
'\n'
读取整行文字,则会将其存储起来。答案 4 :(得分:2)
在C编程中,您应该特别注意以null结尾的字符串。这不是对象。它是指向内存地址的指针。因此,您无法直接将决策的内容与常量字符串进行比较&#34;是&#34;在另一个地址。请改用strcmp()。
请注意&#34;是&#34;实际上是&#34;是\ 0&#34;这将需要4个字节和&#34; \ 0&#34;对strcmp()非常重要,它将在比较循环中被识别为终止。
答案 5 :(得分:1)
这里有几个问题:
您还没有为答案分配足够的存储空间:
char[3] decision;
C字符串是字符串中的字节,后跟ASCII NUL
字节:0x00,\0
。此时您只为ye\0
分配了足够的空间。 (好吧,scanf(3)
会给你yes\0
并将NUL
放在不相关的记忆中.C可能很残忍。)修改为包含空格以终止\0
和修改你的scanf(3)
调用以防止缓冲区溢出:
char [4]决定; / * ...... * / scanf(&#34;%3s&#34;,决定);
(我已经离开了&
,因为简单地给出数组的名称与给出第一个元素的地址相同。这没关系,但我相信这一点更惯用。)
无法将C字符串与==
进行比较。使用strcmp(3)
或strncmp(3)
或strcasecmp(3)
或strncasecmp(3)
来比较您的字符串:
if(strcasecmp(decision, "yes") == 0) {
/* yes */
}
答案 6 :(得分:1)
C有很多lib函数来处理这个问题,但知道你要声明的内容是值得的。
声明
char[3] decision;
实际上是声明一个长度为3的char数组。因此尝试比较
if(decision == "yes")
正在比较文字和数组,因此不起作用。由于C中没有定义的字符串类型,因此您必须使用指针,但不能直接使用指针,如果您不想这样做。在C字符串中实际上是char数组,因此您可以通过两种方式声明它们,例如:
char[3] decision ;
* char decision ;
事实上两者都有效但你在第一个例子中编译器会为你分配内存,但它只能分配3个字节。现在因为C中的字符串是空终止的,所以你需要实际分配4个字节,因为你需要“yes”和null的空间。以第二种方式声明它只是在内存中声明了指向某个地方的指针,但你根本不知道在哪里。然后你必须分配内存以包含你要放在那里的任何内容,否则将会更多地导致SEGFAULT。
要比较从输入中获得的内容,您有两个选项,要么使用strcomp()函数,要么通过迭代决策并将每个字节与“Y”和“E”进行比较来自行完成和“S”,直到你点击null aka 0.
strcomp()有一些变种来处理大写和小写,它们是标准string.h库的一部分。