我是一个C菜鸟,回到学校为我的CS大师所以我花了一些时间来提高我的技能。我想知道是否有人可以为我编译以下代码时遇到问题提供一些帮助。我一直关注WiBit.net上的视频,并在64位Linux环境(Ubuntu 13.10)上进行开发。我使用gedit和gcc编译器没有IDE。
此代码在我的Win 7 VM上运行且没有错误,但是当我尝试在我的主机Linux环境中执行它时,我遇到错误:
源代码:此示例调用strcmp和strcmpi函数
#include <stdio.h>
#include <string.h>
int main()
{
char str1[255];
char str2[255];
printf("str1: "); gets(str1);
printf("str2: "); gets(str2);
if(strcmp(str1, str2) == 0)
printf("Strings match exactly!");
else if(strcmpi(str1, str2) == 0)
printf("Strings match when ignoring case!");
return 0;
}
错误消息(仅限Linux):
$ gcc main.c -o demo -lm -pthread -lgmp -lreadline 2&gt;&amp; 1
/tmp/ccwqdQMN.o:在函数main':
main.c:(.text+0x25): warning: the
中获取'函数是危险的,不应该使用。
main.c :(。text + 0x8f):未定义引用`strcmpi'
collect2:错误:ld返回1退出状态
源代码2:此示例使用strupr和strlwr函数
#include <stdio.h>
#include <string.h>
int main()
{
char str1[255];
char str2[255];
printf("str1: "); gets(str1);
printf("str2: "); gets(str2);
strlwr(str1);
strupr(str2);
puts (str1);
puts (str2);
return 0;
}
错误消息(仅限Linux):
$ gcc main.c -o demo -lm -pthread -lgmp -lreadline 2&gt;&amp; 1
/tmp/ccWnIfnz.o:在函数main':
main.c:(.text+0x25): warning: the
中获取'函数是危险的,不应该使用。
main.c :(。text + 0x57):对strlwr'
main.c:(.text+0x6b): undefined reference to
strupr'的未定义引用
collect2:错误:ld返回1退出状态
如果有人愿意帮助而不是撕裂我,我会详细解释哈哈。我知道,对于最佳实践,我们不应该因缓冲区溢出而使用获取(例如,用户输入750个字符的字符串)。最佳实践将使用fgets而不是我的问题是我是否收到这些错误,因为这些函数不是ANSI C的一部分或什么。它们会显示在我机器上的man文件中,这会让我陷入困境。
提前致谢!
更新: 你们真棒。收集了您的所有建议和意见,并能够修改并制作一个示例程序,用于字符串比较以及转换为上/下。很高兴我能够在两个操作系统上都无错运行。
示例代码:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char str[255];
printf("Enter a string: "); fgets(str,255, stdin);
printf("Here is your original string, my master: %s\n", str);
//Now let's loop through and convert this to all lowercase
int i;
for(i = 0; str[i]; i++)
{
str[i] = tolower(str[i]);
}
printf("Here is a lowercase version of your string, my master: %s\n", str);
//Now we'll loop through and convert the string to uppercase
int j;
for(j = 0; str[j]; j++)
{
str[j] = toupper(str[j]);
}
printf("Here is a uppercase version of your string, my master: %s\n", str);
return 0;
}
答案 0 :(得分:3)
strcmpi问题:strcasecmp()是posix标准,所以在linux中也是如此。
glibc中不存在strupr和strlwr,尽管你可以用一行代码实现它们,如下所示: c - convert a mixed-case string to all lower case
在编译中,首先你可以找到一个警告,因为gcc没有在包含的标题中找到这些函数。在这种情况下,它认为它们被声明为int funcname(void)。但是后来,在链接时,它找不到这个不存在的函数的导出符号,因而无法创建可执行文件。第二个错误是停止编译的原因。
c apis有太多不同,虽然posix标准处理它们,但微软不遵循它。
答案 1 :(得分:2)
正如您所指出的, gets 函数是不安全的,因为它不执行任何边界检查:您使用255个字符的字符串缓冲区调用它,但是如果另一个程序写了一个长于255的行字符,它可以将数据写入进程的堆栈,从而导致您的进程执行恶意代码(或者至少产生分段错误)。
改为使用 fgets :
printf("str1: "); fgets(str1, 255, stdin);
printf("str2: "); fgets(str2, 255, stdin);
如果您仔细阅读了编译器的错误输出,您会注意到它没有对您使用获取发出错误,而是一个警告。如果您修复 strcmpi 调用,您的代码仍应编译并执行。