如何在C ++中读取未知大小的字符串

时间:2016-02-26 16:54:55

标签: c++ dynamic-memory-allocation

我是编码和英语的新手。这是我的代码:

#include<iostream>
#include<cstdio>

using namespace std;

int main()
{
    int n=1;
    char *a = new char[n],c=getchar();
    while((c!=EOF)||(c!='\n'))
    {
        a[n-1]=c;
        c=getchar();
        n++;
    }
    cout << a;
    delete[] a;
    return 0;
}

我正在学习动态内存分配。问题是输入一个长度未知的字符串。我的想法是读取字符串我的单词,当它达到EOF或\ n时停止。你能指出错误吗? 还有一个问题:我被告知new选择了一个指定大小的内存块。那么如果没有足够大的块会发生什么呢? 谢谢你的帮助!

4 个答案:

答案 0 :(得分:3)

#include <iostream>
#include <string>

int main() {
  std::string line;
  // first argument is the stream from whence the line comes.
  // will read to newline or EOF
  std::getline(std::cin, line);
}

答案 1 :(得分:3)

  

[我知道坚持最佳实践和方法是&#34;好&#34;   要做的事情,但OP应该知道为什么当前的代码不起作用   这里的其他答案似乎没有回答那个]

首先,你应该使用C ++字符串类。

其次,如果您想知道为什么您当前的代码不起作用,那是因为:

我。里面的情况是错误的。它说,&#34;如果字符不是\n或者它不是文件结尾&#34;则执行此块。因此,即使您按Enter(c为'\n'),此块仍将执行,因为&#34; c不是EOF&#34;,反之亦然。

II。你只为你的char*分配了1个字节的内存,这显然是不够的。

这应该可以完全复制你想要的东西,但分配的内存是静态的,字符串必须是有限的,

int main()
{
    int n=1;
    char *a = new char[100],c=getchar();
    while(true)
    {
        if(c == '\n' || c == EOF){
            break;
        }
        a[n-1]=c;
        c=getchar();
        n++;
    }
    cout << a;
    delete[] a;
    return 0;
}

答案 2 :(得分:2)

首先,无需使用char*new char[n]。您可以使用std::string

然后你必须问问自己:

  1. 字符串可以包含空格字符吗?
  2. 字符串可以跨越多行吗?
  3. 如果它可以跨越多行,它会跨越多少行?
  4. 如果第一个问题的答案为“否”,您可以使用:

    std::string s;
    cin >> s;
    

    如果第一个问题的答案为“是”且第二个问题的答案为“否”,那么您可以使用:

    std::string s;
    getline(cin, s);
    

    如果第二个问题的答案是“是”,答案会变得更复杂。

    那么,您需要找到更多问题的答案吗?

    1. 硬编码的行数是多少?
    2. 如果没有硬编码,程序如何从用户那里获得该号码?
    3. 根据这些问题的答案,您的代码会有所不同。

答案 3 :(得分:1)

考虑到您的任务的限制(没有std::string,没有std::vector,动态内存分配),我会尝试为您提供修改但可正常运行的代码版本。

  

我的想法是读取字符串我的单词,当它达到EOF或时停止   \ n。你能指出错误吗?

正如molbdnilo指出(c!=EOF) || (c!='\n')总是如此,所以你的循环永远不会结束。

正如mah注意到的那样,你的缓冲区只有1个字符长,而且你不会检查溢出,此外,你忘了在它的末尾添加空的终结符。

你的第二个问题是当new无法分配足够的内存时会发生什么。好吧,它抛出了一个例程,你的程序应该抓住它来管理情况,但你可以做的最好的事情(不是唯一一个,也许是最简单的)是终止你的程序。

这是一个如何根据上述限制完成任务的示例:

#include <iostream>

using namespace std;

const int INITIAL_SIZE = 8;

int main() {
    // the following block of code could rise an exception
    try
    {
        int n = 0;
        char c;

        // allocate some memory to store the null terminated array of chars
        char *a = new char[INITIAL_SIZE];
        // what happens if new fails? It throws an exception of type std::bad_alloc
        // so you better catch it
        int allocated = INITIAL_SIZE;

        // read a charachter from stdin. If EOF exit loop
        while( cin.get(c) )
        {
            // If it's a newline or a carriage return stop
            if( '\n' == c  ||  '\r' == c )
                //^ note that  ^^^ putting the literals first helps avoiding common
                // error like using "=" instead of "==" in conditions
                break;

            a[n] = c;

            // if the array is full it's time to reallocate it
            if ( n == allocated )
            {
                // There are alternatives, of course, but I don't know which library
                // you are allowed to use, so I assume no one and BTW your compiler
                // could be smart enough to recognize the pattern and optimize it

                // allocate a bigger array
                allocated *= 2;
                char *b = new char[allocated];

                // copy the old one in the new one
                for ( int i = 0; i <= n; ++i )
                {
                    b[i] = a[i];
                }

                // release the memory handled by the old one...
                delete[] a; 

                // but keep using the same pointer. Just remember not to delete b
                // so that a allways points to allocated memory.
                a = b;
            }
            // a new character has been succesfuly added
            ++n;
        }

        // now before using a, we have to add the null terminator
        a[n] = '\0';

        // note that a doesn't contain the '\n'
        cout << a << '\n';

        delete[] a; 

        // normal program termination   
        return 0;
    }
    // If new fails to allocate memory a std::bad_alloc exception is thrown
    catch ( const exception &e )
    {
        cout << "Exception caught: " << e.what() << "\nProgram terminated.\n";
        return -1;
    }
}