在指针数组中输入

Posted

技术标签:

【中文标题】在指针数组中输入【英文标题】:Take input in arrays of pointers 【发布时间】:2017-04-01 20:54:25 【问题描述】:

有人可以告诉我为什么不能使用输入流在指向字符串的指针数组中输入输入,如下代码所示:

char *names[5];

for(int i=0; i<5; i++)

cout<<"enter name "<<i+1;   
cin>>names[i];  

【问题讨论】:

ptr 是什么?如果有的话,它与names 有什么关系? 对不起@IgorTandetnik 我的错。刚刚编辑过,如果你现在可以看一下就好了.. cin&gt;&gt;names[i] 期望 names[i] 是一个有效的指针,指向可以存储输入的足够大的字符数组。但在您的示例中,names[i] 是一个包含随机垃圾的未初始化指针。该示例通过访问未初始化的对象展示了未定义的行为。 必须是char * 吗?您可能忘记分配缓冲区,忘记delete 缓冲区或缓冲区可能不够长。 std::string 不是一个选项吗? 能否请您将这段代码编辑得更完美,它将 5 个名称作为指针字符串数组的输入。我尝试将内存动态分配给数组,即使那样似乎也不起作用.. 【参考方案1】:

变量“names”是一个未定义的 char 指针数组。这是你的第一个问题。指针是未定义的,并且没有为它们分配内存。 在您的原始代码示例中,有五个具有未定义值的 char 指针。这就是程序崩溃的原因,因为它试图访问指针中无效地址的内存。 另一个问题是没有分配内存来保存来自标准输入的字符数组。

您可以执行以下操作以使您的原始示例正常工作而不会崩溃:

#include <iostream>
#include <string.h>

using namespace std;

int main(int argc, char** argv)

    char names[5][128];
    memset(names, 0, sizeof(names));

    for (int i = 0 ; i < 5 ; i++ )
    
        cout << "enter name " << i+1 << ": ";   
        cin >> names[i];  
    

    for (int i = 0 ; i < 5 ; i++ )
    
        cout << names[i] << "\n";   
    

这分配了一个由 5 128 个字符串组成的数组。它还使用 memset() 清除数组。

由于这是 C++,所以 C++ 风格似乎更有意义。

#include <iostream>
#include <string>
#include <vector>

using namespace std;

const int NUM_NAMES = 5;

int main(int argc, char** argv)

    vector<string> names;
    names.resize(NUM_NAMES);

    for (int i = 0 ; i < NUM_NAMES ; i++ )
    
        cout << "enter name " << i+1 << ": ";   
        cin >> names[i];  
    

    for (int i = 0 ; i < NUM_NAMES ; i++ )
    
        cout << names[i] << "\n";   
    

【讨论】:

感谢您的替代方案,但这是否意味着对于我的变体,问题是内存分配,指针数组不能在运行时输入?如果是这样,如果我们将内存动态分配给数组指针呢? @MrJLP 注意第一个选项。 cin &gt;&gt; names[i];&gt;&gt; 不知道数组有多少位,如果给定足够的输入,它会兴高采烈地注销数组的末尾。 getlineget 可能是更安全的选择,并且具有处理“Von Doom”等名称的额外优势。 是的,您可以在每次迭代中动态分配内存。在第一个 C 风格示例中,内存是在堆栈上分配的。在第二个 C++ 示例中,字符串包含在向量中。 vector.resize() 是创建 5 个新字符串的原因。当向量“names”超出范围时,它会自动删除其中的字符串实例。 @user4581301 是的,这是一个有效的问题。我刚刚得到了原始代码示例而没有崩溃。一个编写良好的程序将有办法防止用户输入超出任何固定长度缓冲区的界限。 @mwbee 这个答案是否解释了您在原始代码中遇到的问题?【参考方案2】:

免责声明: 使用char* 阅读std::cin 通常是个坏主意,我建议您以后学习如何使用std::string

此外,这个问题更适合codereview.SE,但我暂时忽略它。

这是一个做你想做的事情的例子,但我强烈坚持你避免在任何真实的代码中这样做。

char * names[5];

// Allocate names
for (int i = 0; i < 5; i++)

    // Use 256 characters as a buffer
    // any names longer than that might cause errors
    names[i] = new char[256];


// Do IO
for (int i = 0; i<5; i++)

    // Append std::endl
    std::cout << "enter name " << i + 1 << std::endl;
    // This isn't very robust since the user can give anything as a name,
    // and they can't use spaces because of how cin works in this example.
    std::cin >> names[i];


// Use names
for (int i = 0; i < 5; i++)

    // Printing names is just an example
    // you could write the names to somewhere more important
    // you could copy them to a smaller location to use less memory
    std::cout << names[i] << std::endl;


// Dispose of names when done
for (int i = 0; i < 5; i++)

    // Check pointer isn't null
    if (names[i] != nullptr)
    
        // Never forget to delete
        delete names[i];
    

【讨论】:

如果我们硬编码数组的长度,那么在这个问题上使用指针是没有意义的。所以我可以得出结论,我们无法“stdin”在数组指针中获取输入 b/c 没有为其分配内存,因为这些指针只会将地址存储在内存中的某个位置,然后指向数据输入。 PS我只是在处理一些与指针工作有关的问题,因此不能使用字符串或多维数组。 TIA @mwbee 您提供的示例具有硬编码的数组长度,我只是在调整您提供的代码。我不确定你评论的其余部分应该说什么。指针不会重定向到输入,数据输入被复制到指针指向的内存块中。

以上是关于在指针数组中输入的主要内容,如果未能解决你的问题,请参考以下文章

c语言中如何通过二级指针来操作二维数组

C语言【函数 数组 指针】利用指针求一维数组的数据元素之和

在指针数组中输入

数组和指针+错误

C 语言二级指针作为输入 ( 二维数组 | 二维数组遍历 | 二维数组排序 )

c数组指针的约瑟夫杯问题 初学者求助