简体   繁体   English

预处理程序指令不起作用

[英]preprocessor directive not working

I made a program which removes spaces and makes a string upper case by preprocessor directives .its not changing to uppercase 我制作了一个程序,该程序通过预处理程序指令删除空格并使字符串大写。它不会变为大写

#include <stdio.h>
#include <conio.h>
# define TOUPPER(x) (x-32)
void main(void)
{
    int i,j;
    char str[100],*p;
    clrscr();
    printf("Enter the string:\n");
    gets(str);
    for(i=0;    ;i++)
    {
        if(str[i]=='\0')
        break;
        if(str[i]==' ')
        {
            for(j=i;    ;j++)
            {
             str[j]=str[j+1];
             if(str[j]=='\0')
             break;
            }
         }
         if(str[i]<='a'||str[i]>='z')
         {
            *p=str[i];
            TOUPPER('p');

         }


        }
        puts(str);
    getch();
}

Your TOUPPER('p') does exactly what it should, nothing. 您的TOUPPER('p')完全可以完成任何操作。 You're subtracting 32 from the numeric value of 'p' and then throwing it away. 您要从'p'的数值中减去32,然后将其丢弃。 Note that I'm referring to 'p' the character, not p the pointer. 请注意,我指的是字符“ p”,而不是指针p

Problem is wrong range condition, Macro call with constant argument and you are not assigning the value back. 问题是范围条件错误,使用常量参数调用宏,并且您没有将值赋回去。

if(str[i]<='a'||str[i]>='z')
         {
            *p=str[i];
            TOUPPER('p');

         }

Correction: 更正:

if(str[i]>='a'||str[i]<='z')
         {
            str[i] = TOUPPER(str[i]);
         }

Perhaps this is what you wanted: 也许这就是您想要的:

str[i]=TOUPPER(str[i])

(And don't mess around with those pointer p) (并且不要弄乱那些指针p)

Its because you do 因为你做

TOUPPER('p');

and it is defined as 它被定义为

(x-32)

This changes 'p' to upper-case but don't save it. 这会将“ p”更改为大写,但不保存。

You need to change you define like this 您需要像这样更改定义

#define TOUPPER(x) ((*x)=((*x)-32))

just do call it like this: 只是这样称呼它:

TOUPPER(p);

This isn't what you're asking, but please note you have a serious pointer error in your program: 这不是您要的内容,但是请注意,您的程序中存在严重的指针错误:

char str[100],*p;

  ...

if(str[i]<='a'||str[i]>='z')
     {
        *p=str[i];
        TOUPPER('p');

     }

The pointer p is uninitialized (can be pointing to anywhere in memory), and you are assigning the character str[i] to that pointer's memory location. 指针p未初始化(可以指向内存中的任何地方),并且您正在将字符str [i]分配给该指针的内存位置。 p might be equal to 0x00000000 or 0xCDCDCDCD or something else, but in any case you are writing str[i] to that location without initializing p to an appropriate address. p可能等于0x00000000或0xCDCDCDCD或其他,但是在任何情况下,您都将str [i]写入该位置,而没有将p初始化为适当的地址。

If you feel you must use pointers, you could do it this way (still doesn't fix the range issue that others mentioned, the <= and >= are backwards): 如果您觉得必须使用指针,则可以这样做(仍然不能解决其他人提到的范围问题, <=>=向后):

if (str[i]<='a'||str[i]>='z')
{
   p=&str[i]; // p now points to the address of str[i]
   *p = TOUPPER(*p); // p = the address, *p = the contents of that address
}

Don't believe that using preprocessor macros is always faster than using the functions from <ctype.h> . 不要相信使用预处理器宏总是比使用<ctype.h>的函数更快。 It is highly probable that these functions are in fact implemented as preprocessor macros themselves. 这些功能实际上很可能实现为预处理器宏本身。 Just write code that is easy to understand, and only "optimize" it if it is necessary. 只需编写易于理解的代码,并在必要时仅对其进行“优化”。

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

static void
str_toupper(char *str)
{
    char *p;

    for (p = str; *p != '\0'; p++) {
        if (isspace((unsigned char) *p)) {
            memmove(p + 0, p + 1, strlen(p) - 1);
        }
        *p = toupper((unsigned char) *p);
    }
}

int main(void)
{
    char str[100];

    clrscr();
    printf("Enter the string:\n");
    if (fgets(str, sizeof str, stdin) == NULL)
        return 0;

    str_toupper(str);

    printf("%s\n", str);
    getch();
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM