[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 684
  • Last Modified:

convert character array to string

Hi, I am wondering how to convert a character array to a standard string.

Like:

char buffer[80];
string line;

how to convert the character array buffer to string line?

Thank you very much!
0
anxx0018
Asked:
anxx0018
  • 5
  • 5
  • 4
  • +3
1 Solution
 
burcarpatCommented:
use std::string.assign() as in "line.assign(buffer);"
0
 
entropy12Commented:
you can pass a c-string into the costructor of a string like so:

char buffer[80];
string line(buffer);
0
 
Kent OlsenData Warehouse Architect / DBACommented:

You can also "set" the String variable to the char variable.


char   buffer[80];
String line;


line = buffer;

caution -- if the text at 'buffer' is not zero byte terminated, 'line' may assume the value of a very long string.


Kdo

0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
Kyle AbrahamsSenior .Net DeveloperCommented:
strcopy(line, (string)buffer);
0
 
vinay_krishnaCommented:
The Best way to make a string from char array is to pass char array as an argument to the String Constructor. String is nothing but the collection of chars .
Calling Constructor:
 String line = new String( buffer);

 
0
 
entropy12Commented:
>>The Best way to make a string from char array is to pass >>char array as an argument to the String Constructor. >>String is nothing but the collection of chars .
>>Calling Constructor:
>>String line = new String( buffer);

this forum is for C++, not C#
or else you meant:

*string line = new string(buffer);
0
 
anxx0018Author Commented:
I feel very strange about the two points below:

1. strcopy can not be identified under linux, although I have included <string> in my header files.
Is it MFC function?
Error:`strcopy' undeclared (first use this function)

2. String line = new string(buffer) does not work. There is always error:
conversion from `std::string*' to non-scalar type `
   std::basic_string<char, std::char_traits<char>, std::allocator<char> >'
   requested


Thanks!
0
 
entropy12Commented:
he probably meant strcpy not strcopy
also as i said above String line = new string(buffer)
won't work. you need to use:

string * line = new string(buffer);
0
 
burcarpatCommented:
> "1. strcopy can not be identified under linux, although I have included <string> in my header files."

do not use strcpy unless it is absolutely necessary.  it's a c function and has no place in c++ unless for legacy c api support or for ultimate string performance requirements ( and, even then, there are other alternatives )


> "2. String line = new string(buffer) does not work. There is always error: conversion from `std::string*' to non-scalar type `"

this is also a bad idea ( even if you change "String" to "string*" as suggested, which is the correct syntax, btw).  it kills the purpose of using std::string in the first place.  std::string dynamically allocates and releases its own memory.  why would you want to introduce pointers into that?

...

the first three post, i.e. mine, entropy12's, and Kdo's reflect the correct ways to do this in c++.  the rest is either c and/or do not reflect the c++ philosophy very well ( i.e. avoid pointers as much as possible ).  furthermore, in many stl implementations ( including sgi implementation, which is used by stlport, gcc and borland and considered the standard ) both the constructor and operator= actually internally use assign()
0
 
anxx0018Author Commented:
Burcarpat,

Can you please help me check why the following program does not go into loop? I really could not understand it!

Thanks a lot!

Program:
#include <stdio.h>
#include <stdlib.h>
#include <fstream>

#include <iostream>
#include <string>
#include <map>

using namespace std;

//Min is to return the smaller value of m1 and m2.
int Min(int m1, int m2)
{
  if (m1<m2)
    return m1;
  else
    return m2;
}

//WordCmp is used to compare two strings, if k1 is alphabetically smaller than k2, return 0; if k1 is bigger than k2, return 1; if k1 and k2 are equal, return 2.

int WordCmp(string k1, string k2)
{
  int len1,len2;

  char *s1 = new char[strlen(k1.c_str()+1)];
  strcpy(s1,k1.c_str());

  char *s2 = new char[strlen(k2.c_str()+1)];
  strcpy(s2,k2.c_str());
 
  int n = Min(strlen(k1.c_str()), strlen(k2.c_str()));
 
   for (int i= 0; i<n; i++)
    {
      if (s1[i]<s2[i])
       {
       return 0;
       break;
       }
      else if (s1[i]>s2[i])
     {      
       return 1;
       break;
     }
    }
   return 2;
}


//This function is to sort names alphabetically. First, delete "END" and "̼ @P" from inflowing stream. Then if read-in is smaller than the first name of the array, put it at the first place and put others larger. If read-in is larger than the biggest one, put it at the end of the array. Otherwise, check where is a good place for the new read-in, and then put it there.

int main()
{
  ifstream source("/tmp_mnt/home/anqian/keywords.txt");
  map<int, string> key_array;

  string str_Line;

  if(!source)
    {
      cerr<<"Error opening the File!"<<endl;
      return 1;
    }

  else
    {
      getline(source,str_Line);
      key_array[0]=str_Line;
      getline(source,str_Line);

      while(!source.eof() && str_Line.compare("END")!=0 && str_Line.compare("̼ @P")!=0)
     {
       if (WordCmp(str_Line,key_array[0])==0)
           {
             cout<<key_array.size()<<endl;
             for (int i = key_array.size(); i<1; i--)
               {
                 cout<<"I am in for loop!"<<endl;
                 key_array[i]=key_array[i-1];
               }
             key_array[0]=str_Line;
             getline(source,str_Line);
           }

            else if(WordCmp(str_Line,key_array[key_array.size()-1])==1)
           {
             key_array[key_array.size()]=str_Line;
             getline(source,str_Line);
           }
           
            else
           {
             for (int i=key_array.size(); i=2; i--)
               {
                 if (WordCmp(key_array[i-1],str_Line)==1 && WordCmp(key_array[i-2],str_Line)==0)
                {
                  cout<<"Yes! I am here"<<endl;
                  for(int j=key_array.size(); j<=i; j--)
                    {
                      key_array[j]=key_array[j-1];
                    }
                  key_array[i-1]=str_Line;
                  break;
                }
               }
           
           getline(source,str_Line);
           }
     }
      return 0;
    }

  for(int k=0; k<key_array.size();k++)
    {
      cout<<key_array[k]<<endl;
    }
}

source file:
SIMPLE  
BITPIX  
NAXIS  
EXTEND  
NEXTEND
DATE    
FILENAME
FILETYPE
TELESCOP
INSTRUME
EQUINOX
ROOTNAME
PRIMESI
TARGNAME
RA_TARG
DEC_TARG
PROPOSID
LINENUM
PR_INV_L
PR_INV_F
PR_INV_M
TDATEOBS
TTIMEOBS
TEXPSTRT
TEXPEND
TEXPTIME
POSTARG1
POSTARG2
OVERFLOW
CAL_VER
PROCTIME
CFSTATUS
OBSTYPE
OBSMODE
PHOTMODE
0
 
Kyle AbrahamsSenior .Net DeveloperCommented:
>>do not use strcpy unless it is absolutely necessary.  it's a c function and has no place in c++ unless for legacy c api support or for ultimate string performance requirements ( and, even then, there are other alternatives )

I beg to differ.  C++ is absolutely reverse compatible, after all, it was written in C, and is just easier to use than C.  Anything that you can use in C is available to C++. (though it doesn't work going from c++ to c)  strcpy is also taken from the string class, which is a standard c++ class.  instead of using strcpy, you can also use the = operator:

line = buf;  

plain and simple.
0
 
Kyle AbrahamsSenior .Net DeveloperCommented:
(depending on the compiler, you may have to cast it)

line = (string) buf;
0
 
burcarpatCommented:
ged325,

> "I beg to differ..."

i would suggest reading stroustrup's book for this, who, as we all know, is the creator of c++.  in his book, he suggests use of std::string and its member functions whenever possible and revert back to c-style functions only if necessary.  many other c++ experts such as herb sutter ( exceptional c++ series ) and scott meyers ( effective c++ series ) would agree

here's a quote from stroustrup, 3rd. ed., page 600 for your convenience:

"Whenever possible, C-style strings are best avoided in favor of strings. C-style strings and their associated standard functions can be used to produce very efficient code, but even experience C and C++ programmers are prone to make uncaught "silly errors" when using them."


> "C++ is absolutely reverse compatible, after all..."

this is not correct.  for a detailed discussion of this issue, please see these below articles,

    http://www.cuj.com/articles/2002/0207/0207d/0207d.htm?topic=reference

    http://www.cuj.com/articles/2002/0208/0208c/0208c.htm?topic=reference

    http://www.cuj.com/articles/2002/0209/0209c/0209c.htm?topic=reference


> "instead of using strcpy, you can also use the = operator: ... line = buf;"

if you check sources for your c++ library ( such as gcc's ), you'll see that in majority of the cases, operator= actually internally uses assign().  in some implementations, operator= is defined differently but i have never seen one that uses strcpy
0
 
burcarpatCommented:
anxx0018, no offense, but that's really too much code for a 20 points question.  i can give you a couple of tips, though:

- don't use all those char*s at all.  switch fully to std::string

- you don't need WordCmp.  std::lexicographical_compare does that for you

- your while loop is way too complex.  if it takes more than 30 secs for an experienced programmer to figure out what's going on, that means you need to rewrite it
0
 
Kyle AbrahamsSenior .Net DeveloperCommented:
>> but even experience C and C++ programmers are prone to make uncaught "silly errors" when using them

It's the programmer's fault then, not the language.  If the programmer doesn't make "silly errors", then the functions are quite useful.  Especially when you're trying to write efficient code.

> "C++ is absolutely reverse compatible, after all..."
I meant that you can use all C functions in c++, not the other way around.

> "if you check sources for your c++"

I was not debating how it was implemented.  I was just saying it could be done that way.
0
 
anxx0018Author Commented:
Do not worry about the program any more. I have figured out a good way to deal with it. But I have read your suggestions carefully and try to do good notes from them.



Do you guys know how to use stdin when you have inputs from multiple files?

Thank you very much!
0
 
Kent OlsenData Warehouse Architect / DBACommented:

Back to your problem......  A lot of it is style.

Rewrite the Min() function as a macro:

#define Min(a,b) (a<b?a:b)

This will allow you to use it anywhere in the program with any data type or class that utilizes the '<' operator.  When written as a function, only int (or int compatible types) can be used and you may well want to compare long or float elsewhere in the program.


WordCmp() uses the 'new' operator needlessly.  It creates two new buffers each call and never 'delete's them.  The data that you want is already available to the function.  As an earlier post suggested, use C++ classes and functions.  If you really want to use a C style search, start the function like this:

int WordCmp(string k1, string k2)
{
 int len1,len2;

 char *s1 = k1.c_str();
 char *s2 = k2.c_str();
 
 while (*s1 || *s2)
 {
 /* perform comparisons
 }
 return /* strings are equal */
}



if (condition)
  return;
else
  ...

is wordy and lengthy.

if (condition)
  return;

is sufficient.


Lastly, I don't see a working sort algorithm in your code.  I'll leave it up to you to devise one.


Good Luck,
Kdo
0
 
burcarpatCommented:
ged325,

> "It's the programmer's fault then, not the language.  If the programmer doesn't make "silly errors", then the functions are quite useful.  Especially when you're trying to write efficient code."

of course, ged325.  but, if we follow that logic too keenly, we'll all need to code using assembler.  there is nothing wrong with assembler as far as the functionality goes.  if written correctly, it will always be faster and more memory efficient than anything you can come up with and all the bugs are actually always the programmer's fault.  yet, we don't use assembler and for a reason

function-wise, there is nothing you can't do in c, that you can in c++ ( that doesn't mean they are compatible, though ).  you can even fake class hierarchies and polymorphism, if you want to ( and, in fact, linux people use that kind of stuff all the time ).  sure, it'll be a lot more complex in c, than in c++ but it can be done.  yet, that's not the point.  the point is, this is c++, not c.  just because the legacy support is there, one should not automatically reach for it when other native alternatives exist

majority of the times you don't need the performance gain that *might* be provided by c-style strings anyway ( and, the only way to prove the opposite is to profile the actual code ).  in fact, std::string has certain advantages over char* such as reference-counting and thus for certain cases, it can actually be more optimum than using bare char*s.  another typical example is sorting using strings.  if you fall into the trap of thinking char* is always more efficient than std::string, and c-style functions are always faster than c++ counterparts, you might be surprised when you try to qsort() char*s using strcmp()

unless one understands the inner-workings of char*, std::string and other c-style functions very clearly, one should always choose std::string over char* and c++ functions over c-style functions

...

Kdo,

> "#define Min(a,b) (a<b?a:b)"

i think, that suggestion needs to be revised.   please see:

    http://www.gotw.ca/gotw/077.htm

the main problem is, something like "max(i+=2, j)" will blow up your macro big time and it's not uncommon to find such things in actual code.  because max looks like a function but in reality it is a macro, these things will happen ( and will cause long debugging sessions )

i think the general rule of "use c++, not c" also applies here.  it's generally best to avoid macros, which are a part of c ( c++ intended to remove macros altogether via template support but macros were too practically useful and used too widely for that )

a simple alternative might be:

    template <typename T>
    T
    min(const T& _a,
        const T& _b) {
      return (_a < _b) ? _a : _b;
    }; // min

an even better min/max definition is at

    http://www.cuj.com/experts/1904/alexandr.htm?topic=experts

...

anxx0018,
 
good luck w/ your code...
0
 
anxx0018Author Commented:
Thank you very much for your suggestions.


Do you guys know how to use stdin when you have inputs from multiple files?

Thank you very much!
0
 
vinay_krishnaCommented:
*line = buffer[];
0
 
anxx0018Author Commented:
burcarpat,

Thank you for your help! You are a very skilled programmer!

0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 5
  • 5
  • 4
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now