警告:由于数据类型的范围有限,因此比较始终为真

时间:2012-11-09 06:57:03

标签: c

我正在测试这个应该从用户那里读取输入的函数,但它会引发我的分段错误

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAX_STRING_LENGTH 10

int 
readinput(char *input)
{
    int c;
    int i=0;
    while((c=getchar()) != EOF && c != '\n')  //Here is where the warning occurs.
    {
        input[i]=c;
        i++;
    }
    input[i]=0;
    if(strlen(input)>0)
    {
        if(isalpha(input[0]) && input[1]=='-' && isalpha(input[2]) && strlen(input)==3)
            return 0;
        else if(!strcmp(input, "quit"))
            return 1;
        else if(!strncmp(input, "save ", 5))
            return 2;
        else if(!strcmp(input, "undo"))
            return 3;
    }
    return -1;
}

int main()
{
   char *str;
   printf("write a string\n");
   int nr=readinput(str);
   printf("%d\n", nr);
   printf("%s\n", str);
   return 0;
}

我确实注意到了我犯的愚蠢错误,但仍然存在分段错误,为什么?

5 个答案:

答案 0 :(得分:2)

这是因为EOF(在我的编译器中)被定义为-1而char是无符号字节。所以它总是!=

答案 1 :(得分:2)

 c != '/n' is wrong

 change it to 

  c != '\n'

答案 2 :(得分:2)

c != '/n'应为c != '\n'

\是一个转义字符,在其后跟n的情况下表示换行符。 /n将被视为两个不同的字符,无法与单个char变量进行比较。

至于您的细分错误,您需要在str函数中为main分配一些空间:

char* str = malloc(sizeof(char)*MAX_STRING_LENGTH);

char str[MAX_STRING_LENGTH];

但您还必须确保不要尝试读取字符数超出str数组所能容纳的字符串。

答案 3 :(得分:2)

它出错是因为您从未为str分配空间,并且它指向一个随机位置,导致readinput尝试将数据存储在不存在的位置。

答案 4 :(得分:1)

出现分段错误是因为您已将未初始化的指针传递给函数readinput()。您需要执行以下操作:

char str[4096];

int nr = readinput(str);

您应该传入一个数组的长度,以便被调用的代码可以验证它不会溢出其边界。或者你可以危险地生活,并决定4096足够大,这可能是有人试图故意破坏你的程序。


原始编译器警告是因为多字符常量'/n'的值(类型为int)超出了可以存储在char中的值范围,因此,当c被提升为int时,与!=的(实现定义的)值的'/n'比较必然为真。因此警告:

Warning: comparison is always true due to limited range of data type

所有多字符字符常量都具有实现定义的值。没有可移植的多字符字符常量。

ISO / IEC 9899:2011§6.4.4.4字符常量

  

¶10...包含多个字符的整数字符常量的值(例如,   'ab'),或包含不映射到单字节的字符或转义序列   执行字符,是实现定义的。 ...