use*_*214 0 c syntax lowercase char
我得到一个段.当我尝试从char类型中减去32时(尝试在C中转换为小写而没有tolower())我已经完成了错误.我已经完成了前提条件搜索相关的Q/A线程而没有运气.我也试过'a' - 'A'对于转换值,'32',将其转换为(char*)以及我能想到的任何其他内容.例如:
char* s1 = "Bob";
if (*s1 >= 97 && *s1 <= 122)
*s1 -= 32;
}
Run Code Online (Sandbox Code Playgroud)
有什么建议?
编辑:
在按照下面的帮助后,我仍然得到错误.(对于此示例,我只是尝试将名称的第一个字母更改为小写.)以下是我正在尝试的内容:
char* s1 = "Bob";
printf("\n %s before", s1);
// below I call my string length function to get actual size instead of 100
char* temp = malloc(100);
temp = s1;
if (*temp >= 'A' && *temp <= 'Z'){
*temp -= 32;
}
printf("\n%s after", temp);
free(temp);
Run Code Online (Sandbox Code Playgroud)
另外,为什么我需要为已经在内存中的字符串分配内存?
你不能像这样改变文字字符串 - 它们(通常)在只读存储器中.您需要制作字符串文字的可写副本:
char* name = "Bob";
char* s1 = strdup(name);
...
free(s1); // And you also need this to avoid a memory leak!
Run Code Online (Sandbox Code Playgroud)
您的代码存在许多问题.
char* s1 = "Bob";
Run Code Online (Sandbox Code Playgroud)
字符串文字创建一个只读数组char; 这个数组是静态的,意味着它在程序的整个生命周期中都存在.由于历史原因,它不是const,因此如果您尝试修改它,编译器不一定会警告您,但您应该小心避免这样做.
s1指向该数组的第一个字符.你可能不会修改*s1.为安全起见,您应将指针声明为const:
const char *s1 = "Bob";
Run Code Online (Sandbox Code Playgroud)
如果你想要一个可修改的字符数组,你可以像这样创建它:
char s1[] = "Bob";
Run Code Online (Sandbox Code Playgroud)
现在让我们看看剩下的代码:
if (*s1 >= 97 && *s1 <= 122)
*s1 -= 32;
}
Run Code Online (Sandbox Code Playgroud)
97而122对于数字ASCII码'a'和'z'.32是小写字母和相应的大写字母之间的区别 - 再次,用ASCII.
C语言不保证字符以ASCII或与其兼容的任何字符集表示.例如,在IBM大型机上,字符以EBCDIC表示,其中字母的代码不连续(有间隙),相应的小写字母和大写字母之间的差异为64,而不是32.
EBCDIC系统现在很少见,但即便如此,便携式代码往往比非可移植代码更清晰,即使代码是否适用于所有系统的任何实际问题也是如此.
我相信你知道,最好的方法是使用这个tolower功能:
*s1 = tolower((unsigned char)*s1);
Run Code Online (Sandbox Code Playgroud)
请注意演员表unsigned char.由于历史原因,声明的to*()和is*()函数<ctype.h>表现得很奇怪.他们不参与char辩论; 相反,他们研究int范围内的论点unsigned char.(他们也接受EOF,这通常是-1).如果plain char是有符号的,那么传递一个char恰好为负值的值会导致未定义的行为.是的,这很烦人.
但是你说你不想用tolower.(这很好;学会自己做这样的事情是一个很好的练习.)
如果你愿意假设大写字母是连续的,并且小写字母是连续的,那么你可以这样做:
if (*s1 >= 'a' && *s1 <= 'z') {
*s1 -= 'a' - 'A';
}
Run Code Online (Sandbox Code Playgroud)
这仍然不能移植到非ASCII系统,但如果您没有记住ASCII表,它会更容易阅读.
它也让你的逻辑向后变得更加明显.你说你想转换为小写,但你的代码从小写转换为大写.
或者,您可以使用将小写字母映射到大写字母的查找表:
char to_lower[CHAR_MAX] = { 0 }; /* sets all elements to 0 */
to_lower['A'] = 'a';
to_lower['B'] = 'b';
/* ... */
to_lower['Z'] = 'z';
Run Code Online (Sandbox Code Playgroud)
或者,如果您的编译器支持复合文字:
const char to_lower[CHAR_MAX] = {
['A'] = 'a',
['B'] = 'b',
/* ... */
};
Run Code Online (Sandbox Code Playgroud)
我会留给你填写剩下的代码来使用它.
现在你可以看到为什么tolower和toupper函数存在 - 所以你不必处理所有这些东西(除了unsigned char你需要的奇数演员).
更新:
回答您问题的新部分:
char* temp = malloc(100);
temp = s1;
Run Code Online (Sandbox Code Playgroud)
该赋值temp = s1;不会复制分配的字符串; 它只是复制指针.temp指向100个字节的已分配空间,但随后您temp指向(只读)字符串文字,并且您丢失了对分配空间的任何引用,从而造成内存泄漏.
您无法在C中分配字符串或数组.要复制字符串,请使用以下strcpy()函数:
char *temp = malloc(100);
if (temp == NULL) { /* Don't assume the allocation was successful! */
fprintf(stderr, "malloc failed\n");
exit(EXIT_FAILURE);
}
strcpy(temp, s1);
Run Code Online (Sandbox Code Playgroud)
另外,为什么我需要为已经在内存中的字符串分配内存?
它在内存中,但它是你不允许修改的内存.如果要修改它,则需要将其复制到可修改的位置.或者,正如我上面建议的那样,你可以把它放在读/写内存中:
char s[] = "Bob";
Run Code Online (Sandbox Code Playgroud)
该初始化将字符串复制到数组中s.
| 归档时间: |
|
| 查看次数: |
891 次 |
| 最近记录: |