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!
Like:
char buffer[80];
string line;
how to convert the character array buffer to string line?
Thank you very much!
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);
char buffer[80];
string line(buffer);
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);
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);
>>Calling Constructor:
>>String line = new String( buffer);
this forum is for C++, not C#
or else you meant:
*string line = new string(buffer);
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!
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);
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()
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()
ASKER
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/anqi an/keyword s.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_arra y[0])==0)
{
cout<<key_array.size()<<en dl;
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_ar ray[key_ar ray.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],st r_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
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/anqi
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
{
if (WordCmp(str_Line,key_arra
{
cout<<key_array.size()<<en
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_ar
{
key_array[key_array.size()
getline(source,str_Line);
}
else
{
for (int i=key_array.size(); i=2; i--)
{
if (WordCmp(key_array[i-1],st
{
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.
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;
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
> "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_compa re 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
- don't use all those char*s at all. switch fully to std::string
- you don't need WordCmp. std::lexicographical_compa
- 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.
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.
ASKER
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!
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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!
Do you guys know how to use stdin when you have inputs from multiple files?
Thank you very much!
*line = buffer[];
ASKER
burcarpat,
Thank you for your help! You are a very skilled programmer!
Thank you for your help! You are a very skilled programmer!