c ++一次读入一个c字样的字符串?

时间:2016-03-09 07:02:23

标签: c++ c cin c-strings

在c ++ id中,喜欢一次将一个字符读入一个c样式的字符串。如果没有先创建一个具有设定大小的字符数组(你不知道用户将输入多少个字符),你怎么做呢?既然你不能调整数组的大小,那怎么办呢?我正在考虑这些问题,但这不起作用。

char words[1];
int count = 0;

char c;
while(cin.get(c))
{
    words[count] = c;
    char temp[count+1];
    count++;
    words = temp;
    delete[] temp;
}

6 个答案:

答案 0 :(得分:6)

由于您无法使用std::vector,我假设您也无法使用std::string。如果您可以使用std::string,则可以通过the answer by @ilia提供解决方案。

没有它,你唯一的选择是:

  1. 使用指向动态分配内存的指针。
  2. 跟踪分配的数组的大小。如果要存储的字符数超过当前大小,请增加数组大小,分配新内存,将内容从旧内存复制到新内存,删除旧内存,使用新内存。
  3. 删除功能结束时分配的内存。
  4. 这是我的建议:

    #include <iostream>
    
    int main()
    {
       size_t currentSize = 10;
    
       // Always make space for the terminating null character.
       char* words = new char[currentSize+1];
       size_t count = 0;
    
       char c;
       while(std::cin.get(c))
       {
          if ( count == currentSize )
          {
             // Allocate memory to hold more data.
             size_t newSize = currentSize*2;
             char* temp = new char[newSize+1];
    
             // Copy the contents from the old location to the new location.
             for ( size_t i = 0; i < currentSize; ++i )
             {
                temp[i] = words[i];
             }
    
             // Delete the old memory.
             delete [] words;
    
             // Use the new memory
             words = temp;
             currentSize = newSize;
          }
    
          words[count] = c;
          count++;
       }
    
       // Terminate the string with a null character.
       words[count] = '\0';
    
       std::cout << words << std::endl;
    
       // Deallocate the memory.
       delete [] words;
    }
    

答案 1 :(得分:2)

你问过C风格的数组。在这种情况下,堆栈或动态分配不会为您服务。每次添加新元素时都需要更改数组编号的计数,这是自动无法实现的。每次读取新的chae时,您都必须解决并删除并保留数组。所以你必须选择:

  1. 使用std::vector(为此目的而创建)
  2. 复制std :: vector中的内容并在代码中自己编写(这看起来很糟糕)
  3. std::vector解决方案:

    std::vector<char> words;
    words.reserve(ESTIMATED_COUNT); // if you you do not the estimated count just delete this line
    char c;
    while(cin.get(c)){
        words.push_back(c);
    }
    

答案 2 :(得分:2)

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string s1;
    char c;
    while (cin.get(c))
    {
        if (c == '\n')
            continue;
        s1 += c;
        cout << "s1  is: " << s1.c_str() << endl; //s1.c_str() returns c style string
    }
}

答案 3 :(得分:1)

您有两种方法,首先是使用零大小的数组,在每次输入后删除数组并分配一个大于+1的新数组,然后存储输入。这使用较少的内存但效率低下。 (在C中,您可以使用realloc来提高效率)

其次是使用缓冲区,例如将读取输入存储在固定大小的数组中,当它变满时,将缓冲区附加到主数组的末尾(通过删除和重新分配)。

顺便说一下,你可以使用std::vector自动高效地增加自身的大小。

答案 4 :(得分:1)

如果你开始使用c风格的字符串,那么:

char* words;
int count = 0;

char c;
while(cin.get(c))
{
    // Create a new array and store the value at the end.
    char* temp = new char[++count];
    temp[count - 1] = c;

    // Copy over the previous values. Notice the -1.
    // You could also replace this FOR loop with a memcpy().
    for(int i = 0; i < count - 1; i++)
         temp[i] = words[i];

    // Delete the data in the old memory location.
    delete[] words;

    // Point to the newly updated memory location.
    words = temp;
}

我会做Humam Helfawi建议并使用std::vector<char>因为你使用的是C ++,它会让你的生活更轻松。上面的实现基本上是不太优雅的矢量版本。如果您事先不知道尺寸,那么您将不得不调整内存大小。

答案 5 :(得分:0)

您需要分配任意大小的字符串缓冲区。然后,如果在追加时达到最大字符数,则需要使用realloc放大缓冲区。

为了避免在每个字符上调用realloc(这不是最佳),建议使用增长策略,例如在每次分配时将大小加倍。还有更多微调的增长策略,这取决于平台。

然后,最后,如果需要,您可以使用realloc将缓冲区修剪为精确的附加字节数。