Link to home
Start Free TrialLog in
Avatar of anxx0018
anxx0018

asked on

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!
Avatar of burcarpat
burcarpat

use std::string.assign() as in "line.assign(buffer);"
you can pass a c-string into the costructor of a string like so:

char buffer[80];
string line(buffer);
Avatar of Kent Olsen

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

strcopy(line, (string)buffer);
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);

 
>>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);
Avatar of anxx0018

ASKER

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!
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);
> "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()
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
>>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.
(depending on the compiler, you may have to cast it)

line = (string) buf;
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
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
>> 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.
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!

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
ASKER CERTIFIED SOLUTION
Avatar of burcarpat
burcarpat

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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!
*line = buffer[];
burcarpat,

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