我知道一个char数据类型可以是带符号或无符号的,这取决于具体实现。如果我只是想操作字节,这并不会对我产生太大的困扰。(事实上,我认为char数据类型代表的是字节而不是字符)。
但是我了解到字符串字面值实际上是有符号的char数组(实际上它们不是,但请见下面的更新),函数fgetc()返回unsigned char被转换成int。所以如果我想操作字符,是使用有符号、无符号还是不确定的字符更好?为什么从文件读取字符有一种不同的约定,而字面值却没有?
我之所以问这个问题是因为我有一些用C语言编写的代码,用于比较字符串字面值和文件内容,但是使用带符号还是无符号char*可能会让我的代码出错。
更新1
好的,正如一些人在答案和评论中指出的那样,字符串字面值实际上是char数组,而不是signed char数组。这意味着我应该使用char*来表示字符串字面值,而不用考虑它们是带符号还是无符号的。这使我非常满意(直到我开始使用unsigned char进行转换/比较为止)。
然而,重要的问题仍然存在,如何从文件中读取字符并将其与字符串字面值进行比较。关键在于将���用fgetc()读取的int类型数据(它明确从文件中读取unsigned char)转换为允许带符号或无符号的char类型。让我提供一个更详细的例子。
基本上,我知道我的fgetc()函数返回的是一些经过错误检查后可以编码为无符号字符的内容。我知道char可能是无符号字符,也可能不是。这意味着,根据c标准的实现方式,将其转换为char将涉及没有重新解释的情况。然而,在系统实现为带符号char的情况下,我必须担心那些可以由无符号字符编码但不能由char编码的值(即那些在(INT8_MAX UINT8_MAX]之间的值)。
简而言之,
问题是这样的,我应该(1)复制他们通过fgetc()读取的底层数据(通过强制类型转换指针-别担心,我知道如何做),还是(2)从无符号字符向下转换为char(只有当我知道这些值不会超过INT8_MAX或这些值可以被忽略的情况下才安全)?
但是我了解到字符串字面值实际上是有符号的char数组(实际上它们不是,但请见下面的更新),函数fgetc()返回unsigned char被转换成int。所以如果我想操作字符,是使用有符号、无符号还是不确定的字符更好?为什么从文件读取字符有一种不同的约定,而字面值却没有?
我之所以问这个问题是因为我有一些用C语言编写的代码,用于比较字符串字面值和文件内容,但是使用带符号还是无符号char*可能会让我的代码出错。
更新1
好的,正如一些人在答案和评论中指出的那样,字符串字面值实际上是char数组,而不是signed char数组。这意味着我应该使用char*来表示字符串字面值,而不用考虑它们是带符号还是无符号的。这使我非常满意(直到我开始使用unsigned char进行转换/比较为止)。
然而,重要的问题仍然存在,如何从文件中读取字符并将其与字符串字面值进行比较。关键在于将���用fgetc()读取的int类型数据(它明确从文件中读取unsigned char)转换为允许带符号或无符号的char类型。让我提供一个更详细的例子。
int main(void)
{
FILE *someFile = fopen("ThePathToSomeRealFile.html", "r");
assert(someFile);
char substringFromFile[25];
memset((void*)substringFromFile,0,sizeof(substringFromFile));
//Alright, the real example is to read the first few characters from the file
//And then compare them to the string I expect
const char *expectedString = "<!DOCTYPE";
for( int counter = 0; counter < sizeof(expectedString)/sizeof(*expectedString); ++counter )
{
//Read it as an integer, because the function returns an `int`
const int oneCharacter = fgetc(someFile);
if( ferror(someFile) )
return EXIT_FAILURE;
if( int == EOF || feof(someFile) )
break;
assert(counter < sizeof(substringFromFile)/sizeof(*substringFromFile));
//HERE IS THE PROBLEM:
//I know the data contained in oneCharacter must be an unsigned char
//Therefore, this is valid
const unsigned char uChar = (const unsigned char)oneCharacter;
//But then how do I assign it to the char?
substringFromFile[counter] = (char)oneCharacter;
}
//and ultimately here's my goal
int headerIsCorrect = strncmp(substringFromFile, expectedString, 9);
if(headerIsCorrect != 0)
return EXIT_SUCCESS;
//else
return EXIT_FAILURE;
}
基本上,我知道我的fgetc()函数返回的是一些经过错误检查后可以编码为无符号字符的内容。我知道char可能是无符号字符,也可能不是。这意味着,根据c标准的实现方式,将其转换为char将涉及没有重新解释的情况。然而,在系统实现为带符号char的情况下,我必须担心那些可以由无符号字符编码但不能由char编码的值(即那些在(INT8_MAX UINT8_MAX]之间的值)。
简而言之,
问题是这样的,我应该(1)复制他们通过fgetc()读取的底层数据(通过强制类型转换指针-别担心,我知道如何做),还是(2)从无符号字符向下转换为char(只有当我知道这些值不会超过INT8_MAX或这些值可以被忽略的情况下才安全)?