问题描述
我正在尝试将固定大小的 argv 转换为上限和下限,但它要么给我分段错误,要么只是在 var 上存储乱码。我试过这个:
#include <stdlib.h>
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(int argc,string argv[])
{
string lower = "abcdefghijklmnopqrstuvwxyz";
string upper = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0,n = 26; i < n; i++)
{
lower[i] = tolower(argv[1][i]);
upper[i] = toupper(argv[1][i]);
}
}
或:
string lower = "";
string upper = "";
//check if repeated chars or numbers
for (int i = 0,n = 26; i < n; i++)
{
printf("%c\n",(char) argv[1][i]);
printf("%c\n",tolower(argv[1][i]));
printf("%c\n",toupper(argv[1][i]));
lower += tolower(argv[1][i]);
upper += toupper(argv[1][i]);
}
最奇怪的部分是 printf 给出了正确的值,但它们没有存储在 lower
或 upper
中。我在这里干什么?
解决方法
不能在 C 中使用 +=
附加到字符串。
<cs50.h>
将 string
定义为 char *
。然后 string lower = "";
将 lower
定义为 char *
并将其设置为指向 ""
的第一个字符。 ""
表示空字符串,即第一个也是唯一一个字符为空(零值)字符的字符串,表示字符串的结束。
当应用一个指针时,+= n
会尝试将指针向前移动 n
元素所指向的类型。例如,如果指针 p
指向数组的元素 3,则 p += 4
将使其指向元素 7。
由于 lower
指向只有一个元素的数组元素,因此空字符 lower += tolower(argv[1][i])
试图使其指向数组外。 C 标准未定义该行为。 (除了它可能在 C 实现中,其中 tolower
应用于该字符产生值为 1 的字符。这将修改 lower
以指向数组中的最后一个元素,这是一个特殊的允许进行指针运算的位置。)
使用string lower = "abcdefghijklmnopqrstuvwxyz";
,您有更多空间进行数组运算;对 lower
进行一些添加将起作用。然而,tolower(argv[1][i])
可能太大而无法保留在数组中。
此外,即使指针算法有效,lower += …
也只会改变指针。它不会改变它指向的字符。
为了使您的代码工作,您需要分配足够的内存来保存结果字符串,包括空字符,并且您必须设置 lower
指向该内存,对于 upper
也是如此。您需要的字符数为 strlen(argv[1][i]) + 1
。如果您已经学会了如何使用 malloc
,则可以使用它。如果你有一个固定的赋值来保证 argv[1]
正好是 26 个字符,你可以定义 lower
并通过用 char lower[27];
声明它来为其提供内存,对于 {{1} }.
然后,您必须将字符复制到该内存中,这可以使用 upper
来完成。当您完成将字符复制到数组中时,您应该在它的末尾写一个空字符,以形成一个完整的 C 字符串。 (如果您不打算将数组打印为字符串或以其他方式将其用作字符串,则可以省略此项。)
如果您调用 man toupper
,您将了解到该函数不接受字符串而是一个字符。因此,实现您所追求的目标的一种方法是遍历命令行参数中的每个字符,对其调用 toupper
,然后将结果存储回来。
#include <ctype.h>
#include <stdio.h>
#include <string.h>
void main(int argc,char *argv[])
{
printf("before: %s\n",argv[1]);
for (unsigned int i = 0,n = strlen(argv[1]); i < n; i++) {
argv[1][i] = (char) toupper(argv[1][i]);
}
printf("after: %s\n",argv[1]);
}