[英]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.