【问题标题】:How can I populate a new array with strings passed as command line arguments in argv[]?如何在 argv[] 中使用作为命令行参数传递的字符串填充新数组?
【发布时间】:2022-01-27 10:44:18
【问题描述】:

我对编码比较陌生,尤其是在 C 语言中。我正在尝试创建一个简单的程序,旨在将短语或字符串列表作为填充 char* argv[] 的命令行参数。然后,我想对每个字符执行基于 ASCII 的简单更改(例如使 a => b、b => c、... z => a 等),然后用更改后的字符串填充一个新数组。本质上,新对象将是一个字符数组,就像我相信 argv[] 一样。

这是我的代码,虽然我被各种“指针不兼容的转换赋值**char to string int char variable.....Segmentation fault”样式错误轰炸。

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


int main(int argc, char* argv[])  
{  
    
    char* cipher[argc];  
    for (int i = 1; i < argc; i++)  
    {  
        int n = strlen(argv[i]);  
        for (int j = 0; j < n-1; j++)  
        {  
            cipher[i][j] = argv[i][j];  
        }  
    }  
    for (int i = 0; i<argc-1; i++)  
    {  
        printf("%s\n", cipher[i]);  
    }  
}  

代码将通过命令行运行如下:

./secret the man in the middle is guilty

然后返回一个加扰的形式。我省略了加扰算法,因为这不是我遇到的问题。

我知道我可以更轻松地创建打印更改消息的代码,但我希望能够将新消息存储在数组中以防进一步更改。我不明白为什么我不能只访问特定二维索引的字符值并用它们填充新的“密码”数组。

我不明白什么?

【问题讨论】:

  • 每个字符串都是一个由chars 组成的数组。请注意,您有两个嵌套循环,但您只为 cipher 分配一个维度。
  • 使用cipher[i] = malloc(n+1)cipher中的字符串分配内存。并且不要忘记添加空终止符。
  • @littleadv 如何定义二维数组?是否有类似 a[][] 之类的语法?
  • 查看 Barmar 的评论。您定义了一个指针数组,这是正确的。现在他们每个人都需要指向某个地方。

标签: arrays c multidimensional-array command-line-arguments argv


【解决方案1】:

一堆问题:


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


int main(int argc, char* argv[])  
{  
    

    // first issue: this is only allocating space for "pointers" to
    // strings [argc many] but no space for actual strings so you have to 
    // allocate them.


    // also this is only really workable with c99 (assuming that's the case)
    char* cipher[argc];  

    // this is okay 
    for (int i = 1; i < argc; i++)  
    {  

       // this is where you would allocate space and 
       // perform the copy
        int n = strlen(argv[i]);  
        for (int j = 0; j < n-1; j++)  
        {  
            cipher[i][j] = argv[i][j];  
        }  
    }

   
    for (int i = 0; i<argc-1; i++)  
    {  
        printf("%s\n", cipher[i]);  
    }  
}  


所以至少最低限度:

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

int main(int argc, char* argv[])  
{  
   
    char* cipher[argc];

    // this is okay 
    for (int i = 1; i < argc; i++)  
    {  
         // strdup will return a newly allocated copy
         // and since cipher[] is an array of pointers 
         // you are good to go.
         cipher[i-1] = strdup(argv[i]);
    }

   
    for (int i = 0; i<argc-1; i++)  
    {  
        printf("%s\n", cipher[i]);  
    }  

    // later on after you are finished with cipher 
    // assuming that you still have other things to do
    // you can de-allocate the memory (although not sure if
    // that will be required)

    for(int i = 0; i < argc - 1; i++) {
         free(cipher[i]); // strdup allocated memory cleanup
    }

    // you can no longer use cipher[i] here because it's contents
    // have been destroyed by the free above.
}  

【讨论】:

  • 请注意,strdup 还不是 ISO C 标准的一部分。
  • @AndreasWenzel 我认为它是在 2019 年添加的 en.cppreference.com/w/c/experimental/dynamic/strdup 似乎在说。
  • 非常感谢!我在编码方面的所有经验要么是在 Python 中,要么是在我的 AP Comp Sci 课程中,其中并没有真正解决诸如内存分配之类的本质问题。
  • 不用担心,C 需要大量练习,我已经在其中编程了 30 多年,呵呵,正如@AndreasWenzel 指出的那样,我最终引用了一个可以给你一些帮助的函数对许多非 POSIX 系统感到头疼……我的大脑 C 充满了旧标准;') 但是……strdup 非常适合在大多数 Unix / Linux 系统上使用
  • @AhmedMasud:根据我链接到的页面,strdup 可能会成为即将发布的 ISO C 标准的一部分,该标准可能会在 2023 年投票通过。因此,该标准可能会非正式地成为称为 ISO C23。该功能已纳入the draft standard
猜你喜欢
  • 2018-10-28
  • 2015-07-19
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多