初学C程序员遇到字符串函数问题

时间:2013-12-09 20:55:32

标签: c linux string gcc

我是一个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;
}

2 个答案:

答案 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 调用,您的代码仍应编译并执行。