Dietel "C: How to Program" 书中的这个例子有什么问题?

What is wrong with this example in Dietel's "C: How to Program" book?

我正在学习 Dietel 的 C: How to program。在指针章节中,有这个示例代码:

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

void convertToUppercase(char *sPtr);

int main( void )
{
    char string[] = "cHaRaCters and .98";
    printf( "The string before conversion is: %s", string );
    convertToUppercase( string );
    printf( "\nThe string after conversion is: %s\n", string );
}

void convertToUppercase(char *sPtr)
{
    while(*sPtr != '[=11=]') {
        *sPtr = toupper(*sPtr);
        ++*sPtr;
    }
}

我编译的时候没有问题。但是当我 运行 它时,什么也没有发生。我不知道是什么问题!

您需要增加指针而不是将值从 ++*sPtr 更改为 ++sPtr

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

void convertToUppercase(char *sPtr);

int main( void )
{
    char string[] = "cHaRaCters and .98";
    printf( "The string before conversion is: %s", string );
    convertToUppercase( string );
    printf( "\nThe string after conversion is: %s\n", string );
}

void convertToUppercase(char *sPtr)
{
    while(*sPtr != '[=10=]') {
        *sPtr = toupper(*sPtr);
        ++sPtr;
    }
}

函数中有错别字

void convertToUppercase(char *sPtr)
{
    while(*sPtr != '[=10=]') {
        *sPtr = toupper(*sPtr);
        ++*sPtr;
        ^^^^^^^^
    }
}

相反必须有

        ++sPtr;
        ^^^^^^^

此表达式 ++*sPtr 递增指针指向的字符 sPtr 而此表达式 ++sPtr 递增指针本身。

然而,该代码有几个缺点。

C 标准中的字符串函数约定,它们应该 return 指向目标字符串的指针。所以最好把函数声明成

char * convertToUppercase(char *sPtr);

函数toupper也依赖于它的参数可以表示为无符号字符。

来自 C 标准(7.4 字符处理)

1 The header declares several functions useful for classifying and mapping characters.198) In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.

这样写会更正确

        *sPtr = toupper( ( unsigned char )*sPtr);

在这种情况下,for 循环比 while 循环更合适。

考虑到所有这些,功能可以通过以下方式实现

char * convertToUppercase(char *sPtr)
{
    for ( char *p = sPtr; *p != '[=14=]'; ++p ) {
        *p = toupper( ( unsigned char )*p );
    }

    return sPtr;
}

并称赞

printf( "\nThe string after conversion is: %s\n", convertToUppercase( string ) );