简体   繁体   English

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

[英]I'm having trouble converting argv to upper in C

I'm trying to convert a fixed size argv to upper and to lower but It either gives me segmentation fault or it just stores gibberish on the var.我正在尝试将固定大小的 argv 转换为上和下,但它要么给我分段错误,要么只是在 var 上存储乱码。 I've tried this:我试过这个:

#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]);
    }
}

or:或者:

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]);
}

The strangest part is that the printf's give the right values but they arent getting stored in lower or upper .最奇怪的部分是 printf 给出了正确的值,但它们并没有存储在lowerupper中。 What n00b thing am I doing here?我在这里做什么?

You cannot use += in C to append to a string.您不能在 C 到 append 中使用+=到字符串。

<cs50.h> defines string to be char * . <cs50.h>string定义为char * Then string lower = "";然后string lower = ""; defines lower to be a char * and sets it to point to the first character of "" .lower定义为char *并将其设置为指向""的第一个字符。 "" represents a null string, which is a string whose first and only character is the null (zero value) character, indicating the end of the string. ""表示一个null字符串,该字符串的第一个也是唯一一个字符是null(零值)字符,表示字符串的结束。

When applied a pointer, += n attempts to advance the pointer by n elements of the type it points to.当应用指针时, += n尝试将指针前进它指向的类型的n元素。 For example, if a pointer p is pointing to element 3 of an array, p += 4 will make it point to element 7.例如,如果指针p指向数组的元素 3,则p += 4将使其指向元素 7。

Since lower points to an element of an array with only one element, the null character, lower += tolower(argv[1][i]) attempts to make it point outside the array.由于lower指向只有一个元素的数组元素,因此 null 字符lower += tolower(argv[1][i])试图使其指向数组外部。 The behavior is not defined by the C standard. C 标准未定义该行为。 (Except it could be in a C implementation in which tolower applied to that character yields a character with value 1. This would modify lower to point just beyond the last element in the array, which is a special position that is allowed for pointer arithmetic.) (除非它可能在 C 实现中,其中应用于该字符的tolower会产生一个值为 1 的字符。这将修改lower以指向数组中的最后一个元素,这是一个特殊的 position 允许用于指针运算。 )

With string lower = "abcdefghijklmnopqrstuvwxyz";使用string lower = "abcdefghijklmnopqrstuvwxyz"; , you have more room to do the array arithmetic; ,你有更多的空间来做数组运算; some additions to lower will work.一些添加到lower将起作用。 However, again, tolower(argv[1][i]) is likely too big to remain inside the array.但是, tolower(argv[1][i])可能太大而无法保留在数组中。

Further, even if the pointer arithmetic works, lower += … only changes the pointer.此外,即使指针算术有效, lower += …也只会更改指针。 It does not change the characters it points to.它不会改变它指向的字符。

To make your code work, you need to allocate enough memory to hold the resulting string, including the null character, and you must set lower to point to that memory, and similarly for upper .为了使您的代码正常工作,您需要分配足够的 memory 来保存生成的字符串,包括 null 字符,并且您必须将lower设置为指向该 memory,类似地设置为upper The number of characters you need is strlen(argv[1][i]) + 1 .您需要的字符数是strlen(argv[1][i]) + 1 If you have learned how to use malloc , you can use that.如果你已经学会了如何使用malloc ,你可以使用它。 If you have a fixed assignment that guarantees that argv[1] will be exactly 26 characters, you can define lower and provide memory for it by declaring it with char lower[27];如果您有保证argv[1]正好是 26 个字符的固定分配,您可以定义lower并通过用char lower[27]; , and similarly for upper . ,对于upper也是如此。

Then, you must copy characters into that memory, which you can do with lower[i] = tolower(argv[1][i]);然后,您必须将字符复制到该 memory 中,您可以使用lower[i] = tolower(argv[1][i]); . . When you are done copying characters into the array, you should write a null character at the end of it, to form a complete C string.将字符复制到数组中后,应在其末尾写入一个 null 字符,以形成一个完整的 C 字符串。 (If you are not going to print the array as a string or otherwise use it as a string, you can omit this.) (如果您不打算将数组打印为字符串或以其他方式将其用作字符串,则可以省略它。)

If you invoke man toupper you'll learn that the function does not take a string but rather a character.如果您调用man toupper ,您将了解到 function 不采用字符串,而是采用字符。 So, one way to achieve what you're after is to loop over every character in your command line argument, call toupper on it, and store the result back.因此,实现您所追求的一种方法是遍历命令行参数中的每个字符,对其调用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]);  
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM