我无法在 C 中将 argv 转换为 upper

I'm having trouble converting argv to upper in C

我正在尝试将固定大小的 argv 转换为 upper 和 lower 但它要么给我分段错误,要么只是在 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",(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 给出了正确的值,但它们没有存储在 lowerupper 中。我在这里做什么 n00b 事情?

您不能在 C 中使用 += 附加到字符串。

<cs50.h> 定义 stringchar *。然后 string lower = ""; 定义 lower 为一个 char * 并设置它指向 "" 的第一个字符。 ""表示空字符串,也就是第一个也是唯一一个字符为null(零值)字符的字符串,表示字符串结束。

当应用指针时,+= <i>n</i> 尝试将指针前进 <i>n </i> 它指向的类型的元素。例如,如果指针 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]; 声明它来为其提供内存,对于 [=30= 也是如此].

然后,您必须将字符复制到该内存中,您可以使用 lower[i] = tolower(argv[1][i]); 执行此操作。当你完成将字符复制到数组中时,你应该在它的末尾写入一个空字符,以形成一个完整的 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]);  
}