我正在尝试将字符串转换为大写字母,例如将test.pdf
转换为TEST.PDF
。但是,当我尝试使用printf
打印返回值时,它会打印一些垃圾值。我究竟做错了什么?
char *covertToUpper(char *str)
{
int i = 0;
int len = 0;
len = strlen(str);
char newstr[len+1];
for(i = 0; str[i]; i++)
{
newstr[i] = toupper(str[i]);
}
//terminate string
newstr[i]= '\0';
return newstr;
}
答案 0 :(得分:11)
你得到垃圾的原因是因为你在堆栈上分配“newstr
然后返回它的值。这是C中的一个大禁忌。之后你调用的每个函数,包括{{ 1}}函数本身,将践踏你刚刚分配的内容。
不是以这种方式分配字符串,而是需要使用printf()
或malloc()
为堆分配新的内存,并设置calloc()
指向它。例如,您可以声明:
newstr
当然,当它不再使用时,需要适当地char newstr = malloc(len);
。
答案 1 :(得分:10)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *covertToUpper(char *str){
char *newstr, *p;
p = newstr = strdup(str);
while(*p++=toupper(*p));
return newstr;
}
int main (void){
char *str = "test.pdf";
char *upstr;
printf("%s\n", str);
upstr=covertToUpper(str);
printf("%s\n", upstr);
free(upstr);
return 0;
}
答案 2 :(得分:3)
你正在返回newstr,但它在堆栈上声明,所以当函数结束时,它的未定义会发生什么。您需要将指针传递给新的str或malloc,或者只是转换到位的指针。
在这种情况下,最有用的是传入newstre的指针和newstr的长度(说明你可以在newstr中使用多少空间)。这种方式在转换为大写时你没有绑定malloc,你可以为src和dest传递相同的指针,它将在适当的位置执行)
如果你想要一个具有malloc功能的函数,写一个第二个函数(带有一个暗示其分配内存的名称),它分配内存并使用带有指针的那个
答案 3 :(得分:2)
newstr数组不存在于covertToUpper
函数范围之外。你必须:
free
'),将char newstr[len+1];
更改为char *newstr = malloc(len + 1)
将destinantion指针作为参数(以及安全性的maxlen):
int covertToUpper(const char* src, char* dst, int maxlen) {
int i, len, max;
len = strlen(str);
max = len < maxlen? len : maxlen;
for(i = 0; i < max; ++i) {
dst[i] = toupper(src[i]);
}
dst[i] = '\0';
return i;
}
答案 4 :(得分:2)
您可以在不使用库函数的情况下将字符串转换为大写。使用一些ASCII数学可以是更好的解决方案:
void toUpper(char *text, char *nText){
for(int i=0; i<=strlen(text); i++){
if( (text[i] > 96 ) && (text[i] < 123) ) // if the char is lower case
nText[i] = text[i] - 'a' + 'A'; //make upper
else
nText[i] = text[i]; //do nothing
}
}
函数调用:
char stuff[] = "test.pdf";
char result[100];
toLower(stuff, result);
printf("toLower: %s", result);
答案 5 :(得分:1)
void strupper(char *s) {
while (*s) {
if ((*s >= 'a' ) && (*s <= 'z')) *s -= ('a'-'A');
s++;
}
}
答案 6 :(得分:1)
其他答案已经回答了为什么OP代码不起作用。现在这是一个非常简单的(在我看来)更好的方法:
#include <string.h>
#include <ctype.h>
int strupp(char *s) {
int i;
for (i = 0; i < strlen(s); i++)
s[i] = toupper(s[i]);
return i;
}
因为通常您希望将相同的字符串转换为大写,而不是使用新副本来使用更多内存。如果您确实需要新副本,则可以在调用转换为大写的函数之前始终执行此操作。无需混合任务并使其更复杂。
答案 7 :(得分:1)
稍作修正。 'Z'和'a'之间还有一些其他的符号:[] \ ^等。 您可以使用此限制从0到122
/*A=63 Z=90 a=97 z=122*/
while((i>= 0 && i<=64) || (c>=89 && c<=96)){
必须!对面。
这就是美:
while(str[i])
{
putchar (toupper(str[i]));
i++;
}
答案 8 :(得分:0)
#include<stdio.h>
#include<conio.h>
#include<string.h>
void *TakeString(char*);
void main()
{
char *name;
clrscr();
TakeString(name);
puts(name);
getch();
}
void *TakeString(char *v)
{
int i;
gets(v);
for(i=0;i<strlen(v);i++)
{
v[i]=toupper(v[i]);
}
}