Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c

c-strings

cin

in c++ id like to read input into a c-style string one character at a time. 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;
}
like image 659
Dominic Wasko Avatar asked Mar 09 '16 07:03

Dominic Wasko


People also ask

Can you display a single character as a value in C?

yes, %c will print a single char: printf("%c", 'h'); also, putchar / putc will work too.

How does %s work in C?

%c deals with a char (that is, a single character), whereas %s deals with a char * (that is, a pointer to an array of characters, hopefully null-terminated).

What is the function to read a single character in C?

Read a single character. For example, char ch; scanf("%c", &ch); reads one character and stores that character into ch.

Is char * A string in C?

This last part of the definition is important: all C-strings are char arrays, but not all char arrays are c-strings. C-strings of this form are called “string literals“: const char * str = "This is a string literal. See the double quotes?"


3 Answers

Since you cannot use std::vector, I am assuming you cannot use std::string either. If you can use std::string, you can the solution provide by the answer by @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;
}
like image 163
R Sahu Avatar answered Sep 21 '22 07:09

R Sahu


You asked for C-style array. 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. So you have to options:

  1. Use std::vector (which was created for this purpose)
  2. Duplicate what is inside std::vector and write it yourself during your code( which seems terrible)

std::vector solution:

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);
}
like image 44
Humam Helfawi Avatar answered Sep 23 '22 07:09

Humam Helfawi


#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
    }
}
like image 27
ilia Avatar answered Sep 23 '22 07:09

ilia