【问题标题】:2D array using strings使用字符串的二维数组
【发布时间】:2012-11-21 20:28:06
【问题描述】:

我被一些没有评分的家庭作业困住了(它意味着练习)。

我必须创建一个名为find_name 的函数,它需要两个参数。第一个参数是一个二维的名字(字符串)数组,第二个是一个字符串,用于在二维数组中查找名字,如果找到则函数必须返回1,否则返回0。

当我调用函数(现在是空的)时,我得到了这个warning: passing argument 1 of 'find_name' from incompatible pointer type

这是重要的部分。

在主目录中

 char strNameList[][2] = { { "Luca","Daniel"} ,{"Vivan","Desmond"},{"Abdul","Justin"}, {"Nina","Marlene"},{"Donny","Kathlene"} };

char strFindName[] = "\0";
    printf("Please enter a name to look for: ");
    gets(strFindName);
    nSearch = find_name(strNameList, strFindName);

函数

int find_name(char strNameList[][2], char strLookUp[])

我是 C 新手(我是一名学生),我对字符串(字符串数组等)完全感到困惑。

【问题讨论】:

  • 你想声明什么char * strNameList[][2]char strNameList[][2]
  • 哎呀我有 char strNameList,而不是 char *strNameList

标签: c arrays string


【解决方案1】:

我假设你想要一个 char 指针的二维数组。您在程序中两个 位置的 strNameList 声明都不正确。你有:

char strNameList[][2] = { { "Luca","Daniel"} ,{"Vivan","Desmond"},{"Abdul","Justin"}, {"Nina","Marlene"},{"Donny","Kathlene"} };

但是char[][N] 声明了一个 chars 的二维数组,而不是 char* 因此编译器会警告您将大量指针值分配给类型的项目char

both您的声明(您的变量您的函数参数)更改为:

const char *strNameList[][2]

它声明了一个长度未知的数组,该数组包含两个char*,现在与您的初始化列表匹配。此外,添加 const 是因为 (a) 我假设您不打算在函数中修改该名称列表,并且 (b) 通过初始化程序分配给 char* 的可写字符串文字声明在 C 中是未定义的行为,并在 C++ 中正式弃用,所以无论如何你都不应该使用它。同样,您的查找名称也可能没有被修改,因此也要声明它const

结果:

const char * strNameList[][2] = { 
    {"Luca","Daniel"} ,
    {"Vivan","Desmond"},
    {"Abdul","Justin"}, 
    {"Nina","Marlene"},
    {"Donny","Kathlene"} 
};

在你的功能中:

int find_name(const char * strNameList[][2], const char strLookUp[])

最后但同样重要的是,除非您有一个水晶球,否则您的find_name() 函数无法通过给定的信息了解正在传递的姓名列表中有多少姓名。我宁愿你现在看到这一点,而不是想知道后来发生了什么。您需要 (a) 使用 find_name() 知道的令牌值终止列表,或者 (b) 将列表中的名称数量传递给 find_name()。各有各的,但我更喜欢后者:

int find_name(const char * strNameList[][2], size_t nNameListSize, const char strLookUp[])

并通过以下方式在您的调用方调用它:

find_name(strNameList, sizeof(strNameList)/sizeof(strNameList[0]), strFindName)

【讨论】:

  • +1 for the const 我错过了... - 因为strcpy(strNameList[0][0], "alk"); 至少在使用最近的gcc 时会使应用程序崩溃。
  • "通过初始化程序分配给 char* 的可写字符串文字声明是 C" 的弃用功能。这并不完全正确。它在 C++ 中已弃用,在 C 中有效。C 字符串文字不是 const,但修改它们是未定义的行为:*“[...] 如果程序尝试修改这样的数组,则行为未定义。” (C11 6.4.5/7,字符串文字)
  • @netcoder 我真的需要选择一种语言并坚持下去。每次我和一个人一起工作时,它都会在另一个人面前摩擦。前几天我在 C++ 中声明了一个 VLA,并盯着它看了 10 分钟,试图记住为什么它不能编译。谢谢,先生,我会更新答案。
  • 不一定需要传递数组的大小,因为数组由停止元素终止。请看我对这个模组的回答。
  • @alk sok。盯着足够多的帖子,最终它们都融入了​​一大盘意大利面和马力拉。容易错过的东西。无论如何,我当然愿意。
【解决方案2】:

这样做:

#define STOPPER_NAMELIST NULL

char * strNameList[][2] = { 
  { "Luca","Daniel"},
  {"Vivan","Desmond"},
  {"Abdul","Justin"}, 
  {"Nina","Marlene"}, 
  {"Donny","Kathlene"} 
  {STOPPER_NAMELIST, STOPPER_NAMELIST}
};

size_t sizeNameList(const char * strNameList[][2])
{
  size_t size = 0;

  while ((strNameList[size][0] != STOPPER_NAMELIST) && 
         (strNameList[size][0] != STOPPER_NAMELIST))
    ++ size;

  return size;
}

int find_name(char * strNameList[][2], char strLookUp[])
{
   size_t size = sizeNameList(strNameList);

   ...
}

...

nSearch = find_name(strNameList, strFindName);

此方法使用 char * 数组和 2 条目的开放数组 ([])。


更新:

您可以将停止器元素添加到带有名称的数组中,然后无需将数组的大小与数组本身一起传递,因为始终可以通过扫描数组成员来确定大小,直到找到停止器为止。

【讨论】:

  • 我现在明白了。警告:数组初始值设定项中的多余元素|警告:('strNameList[0]' 的初始化接近)
  • 是的,你也修改了 find_name,我正在寻找旧的..+1
  • 要获得 Luca,只需执行 strNameList[0][0] 并为 Vivan 执行 strNameList[1][0]。 @Omkant
  • Herp derp 我没有将由“[][2]”指示的元素成对分组。现在要构建 find_name,因为所有错误都消失了。
  • 我需要将 2 个参数传递给 find_name。
【解决方案3】:

您的函数find_name() 正在寻找一个二维字符数组,即:

char arr[][2] = { { 'a', 'b'}, ...

如果你想让它们字符串你需要:

char *arr[][2] = { {"John", "Smith"}, ...

然后在你需要的函数参数列表中:

void find_name(char *something[][2])
{
   printf("first name: %s, second name: %s\n", something[0][0], something[0][1]);

在你的 main() 函数中调用它:

find_name(arr);

【讨论】:

    猜你喜欢
    • 2016-05-06
    • 2014-02-28
    • 2021-06-12
    • 2019-01-23
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 2019-09-14
    • 2019-02-18
    相关资源
    最近更新 更多