简体   繁体   English

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

[英]c++ read into c-style string one char at a time?

in c++ id like to read input into a c-style string one character at a time. 在c ++ id中,喜欢一次将一个字符读入一个c样式的字符串。 how do you do this without first creating a char array with a set size (you don't know how many chars the user will enter). 如何在不首先创建具有设置大小的字符数组的情况下执行此操作(您不知道用户将输入多少个字符)。 And since you can't resize the array, how is this done? 既然你无法调整数组的大小,那怎么办呢? I was thinking something along these lines, but this does not work. 我正在考虑这些问题,但这不起作用。

char words[1];
int count = 0;

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

Since you cannot use std::vector , I am assuming you cannot use std::string either. 既然你不能使用std::vector ,我假设你也不能使用std::string If you can use std::string , you can the solution provide by the answer by @ilia . 如果你可以使用std::string ,你可以通过@ilia的答案提供解决方案。

Without that, your only option is to: 没有它,你唯一的选择是:

  1. Use a pointer that points to dynamically allocated memory. 使用指向动态分配的内存的指针。
  2. Keep track of the size of the allocated array. 跟踪分配的数组的大小。 If the number of characters to be stored exceeds the current size, increase the array size, allocate new memory, copy the contents from the old memory to new memory, delete old memory, use the new memory. 如果要存储的字符数超过当前大小,请增加数组大小,分配新内存,将内容从旧内存复制到新内存,删除旧内存,使用新内存。
  3. Delete the allocated memory at the end of the function. 删除功能结束时分配的内存。

Here's what I suggest: 这是我的建议:

#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;
}

You asked for C-style array. 你问过C风格的数组。 Stack or dynamic allocation will not serve you in this case. 在这种情况下,堆栈或动态分配不会为您服务。 You need to change the count of the array number in each time you add new element which is not possible automatically. 每次添加新元素时都需要更改数组编号的计数,这是自动无法实现的。 You have to work around and delete and reserve the array each time a new chae is read. 每次读取新的chae时,您都必须解决并删除并保留数组。 So you have to options: 所以你必须选择:

  1. Use std::vector (which was created for this purpose) 使用std::vector (为此目的创建)
  2. Duplicate what is inside std::vector and write it yourself during your code( which seems terrible) 复制std :: vector中的内容并在代码中自己编写(这看起来很糟糕)

std::vector solution: 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);
}
#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
    }
}

You have two ways, first is to use an zero size array, after each input you delete the array and allocate a new one that is +1 bigger, then store the input. 您有两种方法,首先是使用零大小的数组,在每次输入后删除数组并分配一个大于+1的新数组,然后存储输入。 This uses less memory but inefficient. 这使用较少的内存但效率低下。 (In C, you can use realloc to improve efficiency) (在C中,您可以使用realloc来提高效率)

Second is to use a buffer, for example you store read input in a fixed size array and when it get full, you append the buffer at the end of main array (by deleting and re-allocating). 其次是使用缓冲区,例如将读取输入存储在固定大小的数组中,当它变满时,将缓冲区附加到主数组的末尾(通过删除和重新分配)。

By the way, you can use std::vector which grows the size of itself automatically and efficiently. 顺便说一下,你可以使用std::vector自动高效地增加自身的大小。

If you're set on using c-style strings then: 如果你开始使用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;
}

I would do what Humam Helfawi suggested and use std::vector<char> since you are using C++, it will make your life easier. 我会做Humam Helfawi建议并使用std::vector<char>因为你使用C ++,它会让你的生活更轻松。 The implementation above is basically the less elegant version of vector. 上面的实现基本上是不太优雅的矢量版本。 If you don't know the size before hand then you will have to resize memory. 如果您事先不知道尺寸,那么您将不得不调整内存大小。

You need to allocate a string buffer of arbitrary size. 您需要分配任意大小的字符串缓冲区。 Then, if the maximum number of characters is reached upon appending, you need to enlarge the buffer with realloc. 然后,如果在追加时达到最大字符数,则需要使用realloc放大缓冲区。

In order to avoid calling realloc at each character, which is not optimal, a growth strategy is recommended, such as doubling the size at each allocation. 为了避免在每个字符上调用realloc(这不是最优的),建议使用增长策略,例如在每次分配时将大小加倍。 There are even more fine-tuned growth strategies, which depend on the platform. 还有更精细的增长策略,这取决于平台。

Then, at the end, you may use realloc to trim the buffer to the exact number of appended bytes, if necessary. 然后,最后,如果需要,您可以使用realloc将缓冲区修剪为精确的附加字节数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM