【问题标题】:Two dimensional string array in CC中的二维字符串数组
【发布时间】:2015-11-28 13:53:43
【问题描述】:

我想用 C 语言迭代下面的二维字符串数组;这是迭代的代码:

char list [][] ={{"dan","1"},{"sara","2"},{"loura","3"}};

for(i=0; i < 3;i++){

    for(j=0; j < 2;j++){

        if(strcmp(list[i][0],data)==0)
        {
            /*some code*/              
        }

    }//end column 


}// end row for

我收到了很多警告,例如“数组类型的元素类型不完整”。 我认为问题出在二维数组中。我尝试了其他初始化方式,例如:

 char **list[][]=......

但这也没有用。

【问题讨论】:

  • 你真的知道char **list[][] 是什么吗?不要只是反复试验。
  • 你需要什么?你收到了哪些确切的信息,具体在哪里?定义实际上应该报告错误,而不仅仅是警告。字符串应该改变还是不变?如果非常量:您打算在数组中更改它们还是只更改整个条目?
  • 好吧,这个二维数组不会改变,我用它作为数据库的观点,我需要访问它们并在特定条件下查看它们。但我从未在 c 中使用过二维数组,这就是我感到困惑的原因
  • 顺便说一句,我的数组中写入的字符串不是真实的,因为它们太长了。我想访问数组,比较名字,如果找到我想打印与之关联的数字。
  • char **list[][],不是指向二维字符数组的指针,而是保存字符指针地址的二维指针数组,你不能以这种方式开始。

标签: c arrays string char


【解决方案1】:

根据您的评论,数组永远不会改变,您应该使其保持不变。还使用指向条目的指针。后者避免了提供最大值的需要。每个“字符串”的字符大小并避免占用空间:

const char * const list[][2] = { { "...", "..." } , ... };

这是一个指向char 的二维指针数组。初始化程序会将指针设置为初始化程序中给出的字符串字面量。这是您可以获得的最舒适的(在自动调整内存空间大小的意义上)。编译器可以通过初始化器中的对数来推断外部(最左边!)维度。对于内部尺寸,您必须指定。字符串字面量的大小与数组无关,因为我们使用指针(数据不存储在数组本身中)。

第一个const 告诉编译器指向的对象不会被修改。第二个对指针本身也有同样的意义(这意味着整个数组不会被修改)。

有了这个,你可以使用你在问题中使用的strcmp

strcmp(list[i][0], data)

确保data始终正确终止(即'\0'在末尾)。

更新:根据您的编辑,您希望以数字形式访问第二个条目。也许整数会比字符串更好。为此,您需要一个 struct 的一维数组:

const struct {
    const char *name;
    int number;
} list[] = { { .name = "name", .number = 15 } , ... };

.name =/.number = 部分被指定为初始化器;自 C99 以来的标准。)

用法:

strcmp(list[i].name, data)
int my_number = list[i].number;

这样,您可以更轻松地处理整数部分,并且更轻松地命名两个条目。即使您仍然使用两个字符串,这也可能是更好的方法,因为只有当所有条目都具有相同的语义时,您才应该使用数组,否则 struct 会更合适。

【讨论】:

  • @AMH9:欢迎。想想更新的变体。您可能还会注意到它会产生更好的可读性/可维护性代码;-)
  • const * const list[][] 是什么?
  • @Alexguitar:我在文中解释了consts。您的具体问题在哪里?
  • pastebin.com/SmUJ1NWg 因为这就是我在尝试使用该行代码编译程序时得到的结果。
  • 我想说的是应该是const char * const list[][]
【解决方案2】:

if(strcmp(list[i][0],data)==0)

应该是

if(strcmp(list[i],data)==0)

你想要的是字符串的地址,而不是第一个元素。

【讨论】:

  • @ameyCU 因为如果条件为真,我想访问下一个元素 (list[i][1])
  • @AMH9 是的,我知道这就是您需要 3-d char 数组的原因。之前的评论是为了答案。
  • @ameyCU 是的:printf("%p\n", list[0]);
  • 使用printf 来验证地址是一个非常糟糕的主意。这是因为它没有显示指针的实际类型。另请注意,printf("%p\n", list[0]) 是未定义的行为,因为 printf 需要 void * 来表示 %p
  • @Olaf,在这种情况下这是一个好主意,因为我只是想向 AMH9 展示语法确实解析为地址。此外,该行为是确定性的,因为地址就是地址,无论那里存储什么:%p 处理得很好。
【解决方案3】:

你应该这样声明

char list[][2][6] = {{"dan", "1"}, {"sara", "2"}, {"loura", "3"}};
  1. 它是一个由字符数组组成的数组。所以一个 3D char 数组。您只有 2 对 []
  2. 您必须指定除第一个维度之外的所有维度。说char[3][2][6] 也没什么坏处。
  3. 最后一个大小“6”是最长字符串"loura" 加上以空结尾的char 的大小

【讨论】:

  • 如果我这样做,我的代码中的迭代方法是否仍然有效?
  • C 标准不提供类型 string。将char 序列解释为“字符串”只是惯例。
  • 这个list[i][0] 只会得到名字,例如“丹”然后是“萨拉”。如果这是你想要的,它就是有效的。
  • @Olaf 是的,我知道,这就是为什么我使用指向字符序列的第一个字符的指针。
  • @Olaf 很有趣。刚刚搜索了一个草稿版本,没有出现“字符串”这个词。不知道
猜你喜欢
  • 2021-03-28
  • 2014-01-14
  • 1970-01-01
  • 2016-05-06
  • 2021-04-04
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多