[英]preprocessor directive not working
我制作了一个程序,该程序通过预处理程序指令删除空格并使字符串大写。它不会变为大写
#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();
}
您的TOUPPER('p')
完全可以完成任何操作。 您要从'p'
的数值中减去32,然后将其丢弃。 请注意,我指的是字符“ p”,而不是指针p
。
问题是范围条件错误,使用常量参数调用宏,并且您没有将值赋回去。
if(str[i]<='a'||str[i]>='z')
{
*p=str[i];
TOUPPER('p');
}
更正:
if(str[i]>='a'||str[i]<='z')
{
str[i] = TOUPPER(str[i]);
}
也许这就是您想要的:
str[i]=TOUPPER(str[i])
(并且不要弄乱那些指针p)
因为你做
TOUPPER('p');
它被定义为
(x-32)
这会将“ p”更改为大写,但不保存。
您需要像这样更改定义
#define TOUPPER(x) ((*x)=((*x)-32))
只是这样称呼它:
TOUPPER(p);
这不是您要的内容,但是请注意,您的程序中存在严重的指针错误:
char str[100],*p;
...
if(str[i]<='a'||str[i]>='z')
{
*p=str[i];
TOUPPER('p');
}
指针p
未初始化(可以指向内存中的任何地方),并且您正在将字符str [i]分配给该指针的内存位置。 p
可能等于0x00000000或0xCDCDCDCD或其他,但是在任何情况下,您都将str [i]写入该位置,而没有将p初始化为适当的地址。
如果您觉得必须使用指针,则可以这样做(仍然不能解决其他人提到的范围问题, <=
和>=
向后):
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
}
不要相信使用预处理器宏总是比使用<ctype.h>
的函数更快。 这些功能实际上很可能实现为预处理器宏本身。 只需编写易于理解的代码,并在必要时仅对其进行“优化”。
#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.