【问题标题】:Changing strings to upper within a double pointer array在双指针数组中将字符串更改为上
【发布时间】:2015-02-18 06:20:38
【问题描述】:

我需要转换命令行中给出的参数,例如:$ myprogram hello world

并且单词需要用大写字母打印。除了访问双指针数组以使用 toupper() 进行更改之外,我可以做任何事情

static char **duplicateArgs(int argc, char **argv)
{
    char **copy = malloc(argc * sizeof (*argv));
    if(copy == NULL){
        perror("malloc returned NULL");
        exit(1);
    }

    int i;
    for(i = 0; i<argc; i++){
         copy[i] = argv[i];   
    }
    char **temp;
    temp = &copy[1];
    *temp = toupper(copy[1]); 

    return copy;
}

【问题讨论】:

  • 请正确缩进您的代码。
  • 看来你用的是vim,代码缩进的快捷方式是GG=g
  • char **temp; temp = &amp;copy[1]; *temp = toupper(copy[1]); - 你目前认为这是做什么的?
  • 另外,请注意,当您复制 argv 本身(它是指向字符串指针数组的指针)时,您并没有复制单个字符串。
  • 您需要“转换命令行给出的参数”还是“转换命令行给出的参数”?正如我看到你的例子与hello wordargc 参数duplicateArgs 我想你想处理所有的论点,但接受的答案让我怀疑

标签: c arrays pointers toupper


【解决方案1】:
*temp = toupper(copy[1]);

toupper 转换单个字符,如果要转换整个字符串:

char *temp = copy[1]; /* You don't need a double pointer */
size_t len = strlen(temp);

for (size_t i = 0; i < len; i++) {
    temp[i] = toupper(temp[i]); 
}

【讨论】:

  • @Slider 在一行中:while(*temp++ = toupper(*tem));
  • @GrijeshChauhan,哇,很高兴再次见到你,Mr ASCII-Art :)
【解决方案2】:

我假设传递给您的函数char **argv 的参数是直接从main 传递的,因此它表示一个指向指向每个命令行参数的指针数组开头的指针。

argc表示命令行参数的个数。

在您的函数中,您创建一个新缓冲区,然后将 argv 的内容复制到其中。因此,您正在创建指向命令行参数的指针数组的副本,而不是命令行参数字符串本身。

我猜您打算复制字符串,而不是指向字符串的指针(这样做有什么意义?)。我建议您查看函数 strdup 和/或 strncpy 来复制实际的字符串。

这也解释了“toupper”不能按预期工作 - 不是将单个字符传递给它,而是将指针传递给以空字符结尾的字符串。

【讨论】:

  • 是的,我用 main 调用函数,传递 argc 和 argv,在我的函数中它们以 int argc 和 char **argv 的形式出现你建议我复制字符串,然后应用 toupper() ??
【解决方案3】:

toupper()man page函数原型是

int toupper(int c);

在您的代码中,参数 copy[1] 不是 int 值。

您想要的是检查每个元素,如果它们是小写,则将它们转换为大写。伪代码看起来像

for(i = 0; i<argc; i++){
         copy[i] = malloc(strlen(argv[i])+ 1);  //allocate memory 

for (j = 1; j < argc; j++)
  for (i = 0; i < strlen(argv[j]); i++)
  {
    if (islower(argv[j][i]))   //check if it is lower case
         copy[j-1][i] = toupper(argv[j][i]);
    else
         copy[j-1][i] = argv[j][i];          //do not convert
  }

【讨论】:

  • 正确,因为我试图将指针 copy[1] 指向的字符串中的字符转换为大写。那我该怎么办呢?
  • @Slider 请检查更新的答案。它检查小写然后转换。
  • @dear downvoter,请让我知道downvote背后的原因。请考虑发表评论,以便改进帖子。谢谢。
【解决方案4】:

考虑这个例子:

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

static char **duplicateArgs(int argc, char **argv)
{
    char **copy = NULL;
    // allocate memry for pointers to new lines
    copy = (char **)malloc(sizeof(char *) * argc);
    int line, chr;
    for(line = 0; line < argc; line++)
    {
        // allocate memory for new line
        copy[line] = (char *)malloc(sizeof(char) * (strlen(argv[line]) + 1));
        // copy with changes
        for(chr = 0; chr <= strlen(argv[line]); chr++)
        {
            copy[line][chr] = toupper(argv[line][chr]);
        }
    }
    return copy;
}

int main(int argc, char * argv[])
{
    char ** strs;
    int i;
    strs = duplicateArgs(argc, argv);
    for(i = 0; i < argc; i++)
    {
        printf("%s\n", strs[i]);
    }
    return 0;
}

编辑:

您还可以决定是否使用 argv[0](可执行文件的名称)并根据需要更改代码。还可以添加对malloc 结果的检查,以及其他改进...如果您需要:-)

【讨论】:

    【解决方案5】:

    您在使用toupper() 函数时遇到了错误,因为您试图传入一个字符串而不是单个字母。以下是描述该功能的手册页的摘录:

    DESCRIPTION
         The toupper() function converts a lower-case letter to the corresponding
         upper-case letter.  The argument must be representable as an unsigned
         char or the value of EOF.
    

    您有一个指向指针的指针,您可以将其可视化为类似这样的东西。在 C 中,字符串只是 chars 的数组,因此您需要取消引用两次才能获取第二级数组(单个字母)中的数据。每次添加* 时,您都可以将其视为删除一层指针。您可以将* 运算符视为&amp; 运算符的逆运算符。

    这条线是你的问题线

    temp = &copy[1];
    

    试试这个

    //This is a pointer to an individual string
    char *temp = copy[1];
    //Keep going while there are letters in the string
    while(*temp != NULL) {
        //convert the letter
        toupper(*temp);
        //Advance the pointer a letter
        temp++;
    }
    

    【讨论】:

    • while (*temp != null) 应该是 while (*temp != '\0')
    • @AlterMann 为了清楚起见,我可能应该使用\0,但它的工作方式应该与我编写它的方式相同。 NULL 的类型定义为 0,\0 是八进制数 0,两者保持相同的值因此是等价的。见这里:stackoverflow.com/questions/1296843/…
    猜你喜欢
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 2021-11-07
    • 1970-01-01
    相关资源
    最近更新 更多