I am inclined to suspect that Borland C++ compiler 5.02 is seemingly full of bugs. Even though my C++ codes could be bug free, it reported External errors on compiling and failed to create an EXE file to run.

Thanks to Mr. Salem, I have successfully compiled the above codes using the new and free C++ compiler CODE::BLOCK8.02 suggested by him in another thread. The program now works as it is supposed to work, except for the part on string to numeric conversion.

I still encounter problem with conversion of string variable to numeric variable using strtof() function call. It seems that that function requires a char instead of string for the conversion. Is it possible then to assign the values of a string variable to a char variable and use that function for conversion?
Is there any other way to do the conversion of a string to numeric variable?

The problematic part has been remarked out to prevent failure in compiling the codes.
// convert string to numeric variable
// weight = strtod(concate,&endptr);

Could somebody please help?

Thanks.

// inkey-Working        by YBM
#include <conio.h>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <math.h>
using namespace std;

string spaz(int,string);
string datainp(string,int);
void msg() {cout << "\nPress Esc to Exit, Any other key to continue."; }
void presskey()
{
cout << "\n\nAny other key to continue.";
cin.ignore();
// cin.get();
// system("CLS");
}

void msg2()
{
cout << "\n// INPUT TYPE CONTROL";
cout << "\n// ------------------";
cout << "\n// Weight   Condition 3 Numbers and decimals only ";
cout << "\n\n";
}

char *endptr;
double weight;
std::string sweight;
int xc=0;
int condi;
std::string xcon;
char xconcate;
int getche(void);
int main(void)
{
  const char* xconcate;
  string efield="";
  // Weight Condition 3 Numbers and decimals only
  sweight="";
  efield="Weight";
  condi=3;
  sweight=datainp(efield,condi);
  cout << "\n  Validated Numbers and decimal, Weight: " << sweight << endl;
 return 0;
}
//   Data Entry subroutine
string datainp(string efield,int condi)
{
int xcond=condi;
int c;
int extended = 0;

redo:
std::string concate = "";
msg2();
msg();
condi==xcond;
cout << "\nCondition :" << condi << endl;
cout << "\n\n   Enter "<< efield << ": ";
  do
  {
    c = getche();
    if (c==27) { break; }
    char inp=c;       // assign char from ASCII code Backspace's ASCII code is 8
    if (!c)
      extended = getche();
      if (extended) {     }
      else if (condi==3) {      // Only Numbers and decimal allowed
        if ((c >=48 && c <=57) || (c>=46 && c<=46))
        {
          concate += inp; // string concatenation.. The character isn't extended
        }
        else { concate=spaz(c,concate);}
       }
  } while (c != 13);        // ascii 13 is <enter> or <carriage return>
  int len = concate.length();
  cout << "\n  String length =" << len << " chars" << endl;
  if (condi==3)       // Coversion from string to numeric.
  {
  cout << "\n  Weight entered as string = " << concate;
//  convert string to numeric variable
//   weight = strtod(concate,&endptr);
   cout <<"\n\n  strtod(concate,&endptr) Conversion from string to number is not working.. \n  Test weight is numeric, weight*10 = " << weight*10 << " " << endl;
  }
  return concate;
}  // main terminate

//   SUBROUTINE TO MOVE CURSOR POSITION
string spaz(int xc,string xconcate)
{
  if (xc !=8)    // not backspace
  {
    cout << "\x08";
  }
  else
  {
    int len = xconcate.length();
    if (len >0)
    {
      cout << " ";
      cout << "\x08";
      xconcate=xconcate.substr(0,len-1);
    }
    else
    {
      cout << " ";
    }
  }
return xconcate;
}

Edited 7 Years Ago by Dani: n/a

>>I still encounter problem with conversion of string variable to numeric variable using strtof() function call. It seems that that function requires a char instead of string for the conversion

If you had bothered to read the methods available to std::string you would have seen c_str(), which returns const char*. Next time read about the classes you are using instead of blindly tossing code to the screen hoping the compiler will fix your bugs for you.

And you should not have made this a "code snippet" because it ain't one.

Edited 7 Years Ago by Ancient Dragon: n/a

Dear Ancient Dragon,

Your feedback and advice are noted with thanks.

BTW, how does c_str() work? I will read about c_str() later.

Actually, what is a code snippet supposed to be? I have checked the dictionary. Snippet means short extract, and I have posted a short extract of my program codes in the code window.

I have been wondering where to post the codes otherwise. Is it supposed to be in the comment window then?

Please explain.

A "code snipped" is supposed to be some code you have finished and want to show everyone else to help them solve a similar problem. That's why there are no "reply" or "quote" links in your thread so that others can help you. Unfortunately Dani has decided, unwisely IMO, to mix code snippets in the same forum as c++ questions, confusing people like you who really don't know the difference between them.

>>BTW, how does c_str() work? I will read about c_str() later.
Don't read about it later -- DO IT NOW.

Dear Ancient Dragon,

Thank you very much for your patience and explanations. I am in awe of your acumen and formidable reputation in this forum.

So sorry, Sir for the late reply. I was exhausted after getting less than an hour of sleep during the last 24 hours, meeting deadlines.

I appreciate your methodical approach to C++ programming, and I respect people like you who are disciplined. Being an Ex-USAF, (fighter pilot?), and programmer, it is no wonder that you could contribute so much in this forum.

Because of time constraint, I have developed a bad habit of doing things the quick and dirty way, googling for solutions, studying other peoples codes, and modifying them for my own use without reading up about classes as you have suggested. I must find time to read up on C++ the programming of which I knew almost nothing before I post my first ever codes here a couple of days back. But i do know a little bit of QuickBasic and Foxpro for DOS and Windows, a little bit of battle-field experience, and of course I have known all along that C++ is the most powerful programming language on earth. However, it is not easy to get the hang of it, not like being spoon-fed by those high level languages such as those 4thGL languages.

I googled for answer to the problem raised by me in this thread, and I seem to have found the answer. But, the numeric expression with exponential after more than 7 digits, including the decimal point is not what i expected or desired. I am not sure if the format could be changed to show just numbers and not a scientific expression.

This is the way I have tested the codes for the conversion of a string to characters before using strtod() function call:

Actually, i thought they were the same, string and character variables. But they are not the same. Certain functions can be done on one and not the other and vice vesa, confusing me a lot.

START
*******************************

// cstr2.cpp
// Must compile using CODE::BLOCK
// Borland 5.02 does not work
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
void presskey()
{
cout << "\n\nAny other key to continue.";
cin.ignore();
cin.get();
system("CLS");
}
char *endptr;
double weight=0;
int main()
{
string concate;         // declare a string variable
int len; //  find out the number of characters in the string
cout << "Enter Weight: ";
getline(cin, concate);  // input string
len=concate.length();  //find the number of characters in the string

char xxc[len];  // initialize array
concate.copy( xxc, len ); //fills array in order with characters from the string

weight=strtod(xxc,&endptr);
cout << "Weight = " << weight;

presskey();

return 0;
}

*****************
END


START
**************************************
This is how i have incorporated the strtod() inside my program, where they were remarked out earlier:

    int len = concate.length();
    cout << "\n  String length =" << len << " chars" << endl;
    if (condi==3) {
    //  convert string to numeric variable
    char xxc[len];    // intialise array
    concate.copy(xxc,len); // fills in array with characters from the string
    weight = strtod(xxc,&endptr);    // weight declared as global double

*************************8******************
END


Pending feedbacks and critiques, I would like to consider the problem solved in a couple of days. Any comments?

I would like to pursue the manner numbers are expressed on screen, How to handle it, perhaps in another thread. I will take note of your kind advice and post my question not in the code snippets, lest it be ignored by most of the other participants in this forum.

Thank you for your kind assistance and advice. I got to go back to sleep. Goodnight, Sir.

Regards,

Edited 7 Years Ago by John A: added code tags

wow, a lot to read I wonder if he will.... you are kinda being selfish if you expect him to read it all.

c-style strings like this

char *  myChar = "some text"

is avaible due
1. is valid C ( myChar is a pointer and it can point to any part of the memory)
2. Compatibility issues with C, the predecessor of C++

but working with 'em both is not expected to give you lots of trouble

Hope this code helps

#include <string>
int main()
{

std::string str;
char * c = "No cover!";

str = c; //you can assing a c-string to a string
str[3]='h';//you can access the string as if it were an array

char const * c2 = str.c_str(); //it has to be const 

std::cout << c << std::endl ; 
std::cout << str << std::endl ;
std::cout << c2 << std::endl ;

//note that you cant do the following, it compiles but crashes, the reason is that C++ doesnt store the c-style string as an array

c[3] = 'h';

system("pause");

}

Edited 7 Years Ago by namehere05: n/a

Dear namehere05,

Thank you very much indeed for the clear and succinct explanation on a rather confusing string class to a novice like me.

Like Confucius said, "With great doubts comes great understanding."
You have initiated a process of gradually attaining great understanding, not only for me, but for many others out there, including students and professionals, etc. in my position.

I have tested your codes. Need to use CODE::BLOCK. Need to add #include <iostream>, else errors will be reported and will not compile.

BTW, what C++ compiler are you using?

Regards,

Dear firstPerson,

Thank you for the references to templates on conversions. It is about STL?

Regards,


I have tested your codes. Need to use CODE::BLOCK. Need to add #include <iostream>, else errors will be reported and will not compile.

You got that right

BTW, what C++ compiler are you using?

dev c++ you can find it here (1st page in google for "dev c++")
http://www.bloodshed.net/devcpp.html

Im a novice myself so I feel somehow uncomfortable with your comments, hehe

Comments
Whether you are a novice or expert makes no diiference to me. I value your input because I do learn something useful from you, even though it is something fundamental. Resources could be rubbish put to good use. Rubbish could resources of no use.

You got that right

dev c++ you can find it here (1st page in google for "dev c++")
http://www.bloodshed.net/devcpp.html

Im a novice myself so I feel somehow uncomfortable with your comments, hehe

Dear Sir,
Thanks for the info. I have added dev c++ as my 3rd C++compiler. Since various flavors of C++ are used in this forum, I need to try out the codes on the compiler which works.

Actually, i sincerely appreciate your help very much. Never mind being a novice. It is altruistic, and that is more important.

Surely you're joking Mr. firstPerson. STL is for Standard Template Library.

One of the few times someone has called be Mr.
No I know what STL is, my question was with your response

It is about STL?

I didn't quite get your question.

Edited 7 Years Ago by firstPerson: n/a

One of the few times someone has called be Mr.
No I know what STL is, my question was with your response

I didn't quite get your question.

Just kidding. You have read about Mr. Feynman? It just came to my mind. I could not understand about STL. So, I guess since you understand about STL, you got to be as smart as Professor Feynman. Of course you know what STL mean, else you would not have written about it. Thanks for your input.

I am thankful to all of you -- Frederick2, namehere05, firstPerson and last but not least Ancient Dragon -- for all the help I am receiving, I have a much better understanding about string, c-string (there is a g-string in C++?), and their conversions to numeric variable.

The question raised in this thread is solved. The final program codes for this thread are shown below:

// string2num.cpp    YBM assisted by namehere05, et al.
// String to char conversion, char to numeric conversion using strtod() illegal entries will be ignored.
// Formatted output
// Must compile using CODE::BLOCK
// Borland 5.02 does not work
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <iomanip>
using namespace std;
int c=0;

// Subroutine to fix decimal places
void decima(int &dec)
{
cout << setiosflags(ios::fixed |ios::showpoint) << setprecision(dec);
}

void waiting()
{
cout << "\n\nEsc to Exit.\n";
c=getch();
}
char *endptr;
double weight=0;

int main()
{
  system ("color 0a");     // green text on black background
  string concate;         // declare a string variable
  int len; //  find out the number of characters in the string
  cout << "\n\nThis program uses copy() and c_str() to convert string to char (c-string), \nthen char to numeric. Illegal entries will be ignored instead of program crashing";
  cout << "\n\nNormal rather than exponential and decimal places can be preset.\n\n";
  do
  {
    int dec=10;
    decima(dec);
    cout << "\n\nEnter Weight: ";
    getline(cin, concate);  // input string
    len=concate.length();  //find the number of characters in the string
    char xxc[len];  // initialize array
    concate.copy( xxc, len ); //fills array in order with characters from the string
    char const * c2 = concate.c_str();     // using c_str()
    weight=strtod(xxc,&endptr);
    cout << "\nWeight from copy()  : " << weight;
    weight=strtod(c2,&endptr);
    cout << "\nWeight from c_str() : " << weight;
    cout << "\n\nWeight displayed    : " << setw(20) << weight << endl;
    waiting();
  } while (c !=27);
return 0;
}

In view of my better understanding of c-style string and C++ string, this is an update of some codes posted by namehere05. Some of the new things I learnt are as follows:

1. Add the line "using namespace std;" in order to obviate the need to use std:: before cout and endl, etc., like std::cout <<... to save typing std::

2. C-style strings are arrays. Their elements can be accessed and manipulated, like C++ string.

3. When pointers are used for char* data type, elements of a C-style string, say c can be accessed, but can not be replaced with, say c[3]='h'. However for normal C-Style string declared like chax[]="123.456", elements can be replaced with, say chax[3]='0';

4. strtod() function can be used for the conversion of C-Style string variable to numeric variable for C-Style string declared normally with [] or as pointer type C-Style string. See updated codes below:

Please note that #include <string> is only necessary for Borland. CODE::BLOCK and Dev-C++ do not need it.

// string5    originally written by namehere05.
#include <iostream>
#include <string>
using namespace std;
int main() {
  system ("color 0a");     // green text on black bkgrd
  double numeric;
  string str;
  char *endptr;
  char * c = "No cover!";     // declaration of c-style string
  char chax[] = "123.45";  // Declaraition of c-style string
  string ch = "123.45";   // Decalration of c-style string
  string* pc;
  str = chax; //you can assign a c-string to a string

  cout << "\nSTRING MANPULATIONS AND CONVERSION TO NUMERIC VARIABLE\n\n";
  cout << "\nC-STYLE STRING chax";
  char *cstr = "Hello";
  printf( "\nThe second character of %s is %c.\n",
  cstr, cstr[1] );
  cout << "\nBefore replacement of 3rd char with X, chax : " << chax;
  chax[2]='X';
  cout << "\nAfter replacement of 3rd char with X,chax   : " << chax;
  chax[2]='3';
  cout << "\nAfter replacement of 3rd char with 3, chax  : " << chax;
  cout << "\n\nC++ STRING str and C-STYLE STRING chax MANIPULATION ";
  cout << "\n\nstr's initial value  : "<< str;
  str[3]='0';//you can access the string as if it were an array
  cout << "\nstr after str[3]='0' : " << str;
  pc = &ch; // pc is assigned address of c
  cout << "\n\nch is assigned value          : " << ch;
  cout << "\nAddress of &ch assigned to pc : " << pc;
  cout << "\nContent pointed by *pc        : " << *pc;
  cout << "\n\nchax c-style = " << chax ;
  str=chax;
  cout << "\nstr = chax   = " << str << endl ;
  //cout << "\nc2 from conv = " << c2 << std::endl ;

  //   C-style string manipulation

  chax[3] = 'h';
  cout << "\nafter chax[3] = 'h', content of chax is : " << chax;
  str[3]='0';
  cout << "\nafter str[3] = '0', content of str is   : " << str;
  char const * c2 = str.c_str(); //it has to be const
  numeric = strtod(chax,&endptr);
  cout << "\n\nnumeric from strtod conversion of chax ignoring illegal char onwards  : " << numeric;
  numeric = strtod(c2,&endptr);
  cout << "\n\nnumeric from strtod conversion of str where all numbers are converted : " << numeric;

  std::cout << "\n\n";
  system("pause");
}

Some notes on pointer type string courtesy of www.cplusplus.com is reproduced below:

Declaring variables of pointer types
Due to the ability of a pointer to directly refer to the value that it points to, it becomes necessary to specify in its declaration which data type a pointer is going to point to. It is not the same thing to point to a char as to point to an int or a float.

The declaration of pointers follows this format:

type * name;

where type is the data type of the value that the pointer is intended to point to. This type is not the type of the pointer itself! but the type of the data the pointer points to. For example:

int * number;
char * character;
float * greatnumber;

These are three declarations of pointers. Each one is intended to point to a different data type, but in fact all of them are pointers and all of them will occupy the same amount of space in memory (the size in memory of a pointer depends on the platform where the code is going to run). Nevertheless, the data to which they point to do not occupy the same amount of space nor are of the same type: the first one points to an int, the second one to a char and the last one to a float. Therefore, although these three example variables are all of them pointers which occupy the same size in memory, they are said to have different types: int*, char* and float* respectively, depending on the type they point to.

I want to emphasize that the asterisk sign (*) that we use when declaring a pointer only means that it is a pointer (it is part of its type compound specifier), and should not be confused with the dereference operator that we have seen a bit earlier, but which is also written with an asterisk (*). They are simply two different things represented with the same sign.

Comments please if any.

Regards,

>>Please note that #include <string> is only necessary for Borland. CODE::BLOCK and Dev-C++ do not need it.

That may be true, but its always good programming practice to include it anyway so that the code is portable across compilers.

For example:

int * number;
char * character;
float * greatnumber;

These are three declarations of pointers. Each one is intended to point to a different data type, but in fact all of them are pointers and all of them will occupy the same amount of space in memory (the size in memory of a pointer depends on the platform where the code is going to run). Nevertheless, the data to which they point to do not occupy the same amount of space nor are of the same type: the first one points to an int, the second one to a char and the last one to a float. Therefore, although these three example variables are all of them pointers which occupy the same size in memory, they are said to have different types: int*, char* and float* respectively, depending on the type they point to.

It's more of a common convenience these days, but strictly speaking I don't believe that's true. I wouldn't dwell on it all that much, though.

>>Please note that #include <string> is only necessary for Borland. CODE::BLOCK and Dev-C++ do not need it.
That may be true, but its always good programming practice to include it anyway so that the code is portable across compilers.

Agreed. That is a very good piece of advice. I will remember that. Thanks.

It's more of a common convenience these days, but strictly speaking I don't believe that's true. I wouldn't dwell on it all that much, though.

Dear Dave,

Thanks for the link which opens up a whole new (old?) world for me and I believe for many of us in this forum. It is interesting to note how mainframes, mini computers and old 8086 PCs handle pointers * to different data type. I am curious to know how new Dual core or C2D PCs handle it?

But, more importantly what is the real purpose of such pointers to data type? Is there any advantage? Is it because it is faster or save on memory usage? If there is none, can we do away with it completely?

My understanding is that if you declare a string array, say arrcon[5], all 6 elements use the same amount of memory, say 4 bytes each irrespective of their sizes, e.g. arrcon[0]="A" and arrcon[1]="ABCDEFGHIJKLMNOPQRSTUVWXYZ" occupy the same amount of memory in stack. It is because the contents of an array -- the data -- are not stored in the array, but are stored in the heap memory, where the OS handles swapping from disk to ram, when the ram is insufficient. The stack memory could be only 1 MB, whereas the heap memory could be 3GB.

Is it right to say that C-style string were in use during the early days of computers when memory was expensive? Is that why there was a need to be stingy in memory usage, the need to specify the size of each element of an array, like char chax[7] for an 7 byte string ending with a '\0' terminator ?

C++ string class on the other hand can handle strings without such restrictions.

Nowadays, CPUs and rams are getting cheaper and cheaper, while getting faster and faster, complying with Moore's law. DDR2 is much cheaper than DDR1, and much cheaper than SDRAM, and much much faster, viz., DDR2, upto 800MHz, DDR1, 400MHz, SDRAM, 133MHz. Now DDR3 can go up to 1600MHz.

So, basing on what Dave, said, I gather that the pointer * to data type could be something of the past, and getting obsolete.

Actually, is there any justification for its use in modern C++?

I understand that we need to know about C-style strings because many old C/C++ programs used them. So, if new C++ programs only uses C++ strings, there will be no necessity to go back to C-style strings and pointers *, and C++ programmers can move forward with new C++classes, which are more intuitive, efficient and easier to handle, right?

I am sure some C++ veterans can throw some light on the above questions.

This question has already been answered. Start a new discussion instead.