Thread: Setting String equal to char array?

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    29

    Question Setting String equal to char array?

    Is there any way of putting a string of characters into a character array? I am trying to read in input as chars, but I want the spaces to be read as well, and so far the only way I could get this to work is to use the getline function with a string. But I already wrote code to transform the letters in the char array into actual numbers. Thats why I want to be able to make this conversion. Otherwise is there any other way of converting a string into numerals?
    Last edited by Stunner; 07-22-2007 at 10:27 PM.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    to you last question - yes - stringstream
    to the first... hmm some of the getline versions are capable of doing this... but the stringstream solution is more C++- style like...
    Code:
    std::string test("10 12.3");
    std::stringstream ss(test);
    int x;
    double y;
    ss >> x >> y;
    something like that
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Or you could loop through the string and get the characters using operator [].

    Code:
    std::string someString = "123 456 789";
    
    for(int i = 0; i < someString.length(); i++){
        char c = someString[i];
    }//for
    But vart's method is the prefered C++ way, and the way I would do it .

    Also you can get the c style string using the .c_str() member of the string class.
    Code:
    std::string someString = "123 456 789";
    
    const char *cstring = someString.c_str();
    Note: The char* returned from c_str() is const so you are not intended to modify it.
    Last edited by prog-bman; 07-22-2007 at 11:02 PM.

  4. #4
    Registered User
    Join Date
    Jul 2007
    Posts
    29
    Thanks a lot for the replies, I'll update you all when I try implementing it in my code, thanks.

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If you are able to get what you need with a std::string, why would you want to switch to plain char arrays later? Is there anything you can do with char arrays that you can't do with std::string?

    If you have a good reason for that, there's a getline version that reads into char arrays.

    prog-bman: To do it properly, I guess you'll need to strcpy what c_str returns to the char array. Otherwise the original string might go out of scope too early.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Registered User
    Join Date
    Jul 2007
    Posts
    29
    I have already written code to convert a char array into an actual value(took me some time and it is working well). Here is the code:

    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    struct node
    {
    float num;
    char opr;
    char type;
    node* next;
    };
    
    void printList(const node*);
    //entry* insert(int n, node* h);
    //entry* deleteNode(int n, node* h);
    float arrayToInt(char hold[], int value[]);
    void input(char hold[5], int value[5]);
    
    int main()
    {
    node *temp, *head = 0;//starts out empty
    char hold[5];
    int value[5], i;
    float fltval;
    
    	input(hold, value);
    	
    	fltval = arrayToInt(hold, value);//converting array based number to float
    
    	cout << fltval;
    
    	return 0;
    }//main
    
    /****************************************/
    //Converts an array of ints to a float value
    
    float arrayToInt(char hold[], int value[])
    {
    int L, i, j;
    float val = 0;
    float valtab[5] = {1, 10, 100, 1000, 10000};
    //                 1   2   3     4     5
    
    	L = strlen(hold);
    	for(i = 0, j = L - 1; i < L; i++, j--)
    	{
    		val = val + (value[i] * valtab[j]);
    	}//for
    
    	return val;
    }//arrayToInt
    
    /*****************************************/
    //Takes in input
    
    void input(char hold[5], int value[5])
    {
    int i;
    
    	cout << "Enter an algebraic equation in reverse polish notation(type 'stop' to end): ";
    	cin >> hold;
    
    		for(i = 0; hold[i]; i++)
    		{
    			if(isdigit(hold[i]))
    			{
    				value[i] = hold[i] - 48;//converting to int from char	
    			}//if
    		}//for
    
    	return;
    }//input
    I want to be able to use most of this code, so I just want to read it as a char array to make things compatible.

  7. #7
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    yikes. hold only contains 5 characters, is that enough? You are running the risk of a buffer overrun using that method. That is why things like std::string are preferred. Lookup stringstreams like vart stated in his post, this would make you life much easier.

    Code:
    std::string hold;
    std::string value;
    
    getline(std::cin, hold);
    
    for(int i = 0; i < hold.length(); i++){
        if(isdigit(hold[i])){
            value.push_back(hold[i]);
        }
    }
    This would be a semi - C++ way of doing what you are trying to achieve. But like I said stringstreams are much preferred.

  8. #8
    Registered User
    Join Date
    Jul 2007
    Posts
    29
    Aye, thanks. Hold only has 5 because I was planning on only allowing up to 5 digits for my calculator.

    Edit: Forgot to make the arrays have 6 slots.
    Last edited by Stunner; 07-23-2007 at 01:36 PM.

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I have already written code to convert a char array into an actual value(took me some time and it is working well).
    Working well?

    If I type "12345", I get 12345. - OK, but... if the char array size is 5, where's the room for the null terminator? Works through pure luck...

    "123456" gives me 7.92481e+033.
    "12.3" gives 1283.
    "-23" gives 2.00925e+011.

    Also, if it only works with (positive) integers (of limited range), why pretend that you are converting something to float?

    And holding x-48 in a separate array seems like a waste of both time and memory: you only need the results once and you can calculate it where you are doing the conversion.

    --------------------

    I don't mean to be too harsh, but the amount of work and the fact that you rolled it yourself doesn't justify keeping bad code around once you've found a better way. A few lines using stringstreams is all you need to get a non-buggy string to float conversion.

    Refactoring, or reworking (sometimes throwing out) bad code is a usual thing when coding.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    Registered User
    Join Date
    Jul 2007
    Posts
    29
    Quote Originally Posted by anon View Post
    Working well?

    If I type "12345", I get 12345. - OK, but... if the char array size is 5, where's the room for the null terminator? Works through pure luck...

    "123456" gives me 7.92481e+033.
    "12.3" gives 1283.
    "-23" gives 2.00925e+011.

    Also, if it only works with (positive) integers (of limited range), why pretend that you are converting something to float?

    And holding x-48 in a separate array seems like a waste of both time and memory: you only need the results once and you can calculate it where you are doing the conversion.

    --------------------

    I don't mean to be too harsh, but the amount of work and the fact that you rolled it yourself doesn't justify keeping bad code around once you've found a better way. A few lines using stringstreams is all you need to get a non-buggy string to float conversion.

    Refactoring, or reworking (sometimes throwing out) bad code is a usual thing when coding.
    Ey man, thanks for all the input and advice, I really really appreciate it, but you guys are really pro at this and are telling me to do more advanced things which I havn't learned. I would just like to design the code with concepts that I am fairly solid on and see how well I do. Don't take this the wrong way, I really appreciate your help and totally respect your concerns. You are totally right. But I just want to make a simple program(no matter how awkward it may be) that I can understand. I don't want to design this by introducing new concepts. Also, I am trying to design this according to my teacher's specifications:

    ================================================== ============

    "There are many ways of specifying an algebraic equation. The one that most of us are accustomed to is called infix notation(i.e. 3 + 4). Another way of writing this would be (3 4 +). This is called reverse polish notation. Write a program that will read in a polish string and calculate the value of the string. The algorithm for solving this problem can be done with 2 linked lists, a polish queue and an evaluation stack.

    a. Put the poish string into the polish queu.
    b. If the polish queue is empty, halt with the top of the evaluation stack as the answer.
    c. If polish queue is not empty, pop the top of the polish queue into x.
    d. If x is an operator, pop the evaluation stack twice, into arg2 and arg1 in that order. Compute arg1 operator arg2 (operator is in x), and put the result onto the evaluation stack. Go to step (b).
    e. If x is a value, then push x onto the evaluation stack; then go to step (b).

    For example, take the polish string 13, 4, -, 2, 3, *, +
    If the above characters were entered into an RPN calculator the mathematical expression (13 - 4) + (2 * 3) would be calculated, resulting in an answer of 15."

    ================================================== =============

    Well I think I solved my getting input problem, but I have a new problem. Garbage is printed after executing the arrayToInt function. I have tried reinitializing values but that doesn't do it. I am stumped as of now. Here is my code:

    Code:
    #include <iostream>
    
    using namespace std;
    
    struct node
    {
    float num;
    char opr;
    char type;
    node* next;
    };
    
    void printList(const node*);
    //entry* insert(int n, node* h);
    //entry* deleteNode(int n, node* h);
    float arrayToInt(char hold[], float value[]);
    
    int main()
    {
    node *temp = 0, *head = 0;//starts out empty
    float fltval;
    int i, j, n = 0;
    char string[80];
    
    	cout << "Enter an algebraic equation in reverse polish notation(type 'stop' to end): \n";
    	cin.getline(string, 80);
    
    	cout << "Output from func arrayToInt:\n";
    	while(string[n] != '\0')
    	{
    	float value[15] = {0};
    	char part[15] = {'O'};
    
    		for(j = 0; (string[n] != ' ') && (string[n] != '\0'); j++, n++) 
    		{
    			part[j] = string[n];
    		}//for
    		n++;
    
    		for(i = 0; part[i]; i++)
    		{
    			if(isdigit(part[i]))
    			{
    				value[i] = part[i] - 48;//converting to int from char	
    			}//if
    		}//for
    	
    		fltval = arrayToInt(part, value);//converting array based number to float
    
    		cout << fltval << endl;
    
    		head = new node;
    		head->num = fltval;
    		head->next = temp;
    		temp = head;
    
    	}//while
    		cout << "Output from linked list:\n";
    		printList(head);
    
    
    	return 0;
    }//main
    
    /***************************************/
    //Prints list of Nodes
    
    void printList(const node* pointer)
    {
    	while(pointer != 0)
    	{
    		cout << pointer->num << endl;
    		pointer = pointer->next;
    	}//while
    
    }//printList
    
    /****************************************/
    //Converts an array of ints to a float value
    
    float arrayToInt(char part[], float value[])
    {
    int L = 0, i, j;
    float val = 0;
    float valtab[5] = {1, 10, 100, 1000, 10000};
    //                 1   2   3     4     5
    
    	L = strlen(part);
    	for(i = 0, j = L - 1; i < L; i++, j--)
    	{
    		val = val + (value[i] * valtab[j]);
    	}//for
    
    	return val;
    }//arrayToInt
    I think I will be able to solve this issue, but any additional insight and commentary is welcomed. Thanks!

  11. #11
    The larch
    Join Date
    May 2006
    Posts
    3,573
    float arrayToInt(char hold[], float value[]);
    Talk about misleading names.

    If you think stringstreams are too advanced (they are basically the same things as cout and cin, except that input/output don't go to a console but to a string buffer instead), may-be you could first take a look at atoi which already does what you need.

    If you really need to implement this functionality yourself, this is at least how the prototype of your function should look like.

    One thing, there shouldn't be a float in sight. You are simply working with int-s. Converting to floats is trickier than that.

    But the assignment looks challenging enough not to waste time on reimplementing a low-level function.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  12. #12
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Another thing that is wrong is the lookup table for powers of ten. You are still only prepared for 5-digit values. Actually you don't need the table at all. Initialize a variable multiplier to 1. Loop through the character array backwards adding the product of the digit value of the character and multiplier to current result. Each iteration through the loop multiply multiplier by 10.

    Also you should be doing the x - 48 (or better yet x - '0') inside the arrayToInt function. You don't need a separate array to store this temporary result.

    By the way, are you going to implement linked list, stack and queue yourself as well? Standard C++ libraries provide these too. While I admit that it is useful to learn how to implement them, if you don't know 1) how the standard ones look like, 2) about classes, you are in danger of ending up with quite messy code that is rather C than C++ except for the use of cout/cin...
    Last edited by anon; 07-23-2007 at 04:26 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  13. #13
    Registered User
    Join Date
    Jul 2007
    Posts
    29
    Hey anon, thanks for the replies. I think the table is fine because this isn't supposed to handle very large numbers in any case. I used floats instead of ints because I didn't want the compiler to round up or down with ints. Also I wasn't sure if ints could hold numbers of 5 digits so I chose floats. I don't care about using decimals so that is no biggie. This program is half finished and is still a work in progress, I am just beginning to implement the linked list now and am going to start making the algorithms. I know about Classes and all that good stuff, but my teacher in my current course has not introduced that stuff as yet so I don't believe I can use it.

    I took some of your input and updated the code and also managed to fix that bug I was getting. Here it is:

    Code:
    #include <iostream>
    
    using namespace std;
    
    struct node
    {
    float num;
    char opr;
    char type;
    node* next;
    };
    
    void printList(const node*);
    //entry* insert(int n, node* h);
    //entry* deleteNode(int n, node* h);
    float arrayToFloat(char part[]);
    
    int main()
    {
    node *temp = 0, *head = 0;//starts out empty
    float fltval;
    int j, n = 0;
    char string[80];
    
    	cout << "Enter an algebraic equation in reverse polish notation(type 'stop' to end): \n";
    	cin.getline(string, 80);
    
    	cout << "Output from func arrayToInt:\n";
    	while(string[n] != '\0')
    	{
    	//float value[15] = {0};
    	char part[15] = {'O'};
    
    		for(j = 0; (string[n] != ' ') && (string[n] != '\0'); j++, n++) 
    		{
    			part[j] = string[n];
    		}//for
    		n++;
    
    		if(string[n] != '\0')
    		{
    			fltval = arrayToFloat(part);//converting array based number to float
    			cout << fltval << endl;
    
    			head = new node;
    			head->num = fltval;
    			head->next = temp;
    			temp = head;
    		}//if
    
    	}//while
    		cout << "Output from linked list:\n";
    		printList(head);
    
    
    	return 0;
    }//main
    
    /***************************************/
    //Prints list of Nodes
    
    void printList(const node* pointer)
    {
    	while(pointer != 0)
    	{
    		cout << pointer->num << endl;
    		pointer = pointer->next;
    	}//while
    
    }//printList
    
    /****************************************/
    //Converts an array of ints to a float value
    
    float arrayToFloat(char part[])
    {
    int L = 0, i, j;
    float val = 0, value[15] = {0};;
    float valtab[5] = {1, 10, 100, 1000, 10000};
    //                 1   2   3     4     5
    
    	for(i = 0; part[i]; i++)
    	{
    		if(isdigit(part[i]))
    		{
    			value[i] = part[i] - '0';//converting to int from char	
    		}//if
    	}//for
    	
    	L = strlen(part);
    	for(i = 0, j = L - 1; i < L; i++, j--)
    	{
    		val = val + (value[i] * valtab[j]);
    	}//for
    
    	return val;
    }//arrayToFloat

  14. #14
    Registered User
    Join Date
    Jul 2007
    Posts
    29
    I find that whenever my linked list prints, it is a stack, which I do not want. But since I have to design the linked lists myself I was thinking about making a doubly linked list that would be made as the original was, then it would be copied towards the end. I have done a lot of it but there must be an invalid address or something because whenever it tried to execute my computer reports a system error. I have tried debugging with no success... If anyone could figure out the problem that would be great. I have pinpointed the problem to one line (I commented the line).

    The code:

    Code:
    #include <iostream>
    
    using namespace std;
    
    struct node
    {
    float num;
    char opr;
    char type;
    node* next;
    node* prev;
    };
    
    void printList(const node*);
    //entry* insert(int n, node* h);
    //entry* deleteNode(int n, node* h);
    //entry* PQInit(entry* h, entry* PQh);
    float arrayToFloat(char part[]);
    
    int main()
    {
    node *temp = 0, *head = 0;//starts out empty
    node *PQt = 0, *PQh = 0, *PQp = 0;//Polish queue
    float fltval;
    int j, n = 0, flag;
    char string[80];
    
    	cout << "Enter an algebraic equation in reverse polish notation(type 'stop' to end): \n";
    	cin.getline(string, 80);
    
    	cout << "Output from func arrayToInt:\n";
    	while(string[n] != '\0')
    	{
    	char part[15] = {'O'};
    
    		for(j = 0, flag = 0; (string[n] != ' ') && (string[n] != '\0'); j++, n++) 
    		{
    			part[j] = string[n];
    			if(!isdigit(part[j]))//if character
    			{
    				flag = 1;
    			}//if
    		}//for
    		n++;
    
    		if(flag == 0)//if part consists of int
    		{
    			if(string[n] != '\0')
    			{
    				fltval = arrayToFloat(part);//converting array based number to float
    				cout << fltval << endl;
    
    				head = new node;
    				head->num = fltval;
    				head->type = 'N';
    				head->next = temp;
    				temp = head;
    				//setting up PQ
    				PQh = new node;
    				PQh->next = PQt;
    				PQt = PQh;
    				PQp->prev = PQt;//this line causes a problem
    				PQp = PQh;
    			}//if
    		}//if
    		else
    		{
    			if(string[n] != '\0')
    			{
    				head = new node;
    				head->opr = part[0];
    				head->type = 'O';
    				head->next = temp;
    				temp = head;
    				//setting up PQ
    				PQh = new node;
    				PQh->next = PQt;
    				PQt = PQh;
    				PQp->prev = PQt;
    				PQp = PQh;
    			}//if
    		}//else
    
    	}//while
    
    	//PQh = PQInit(head, PQh);
    	cout << "Output from linked list:\n";
    	printList(head);
    	
    
    	while(head->next != 0)
    	{
    		if(head->type == 'N')
    			PQh->num = head->num;
    		else
    			PQh->opr = head->opr;
    
    		head = head->next;
    		PQh = PQh->prev;
    	}//while
    
    	printList(PQh);
    
    	return 0;
    }//main
    
    /***************************************/
    //Prints list of Nodes
    
    void printList(const node* pointer)
    {
    	while(pointer != 0)
    	{
    		if(pointer->type == 'N')
    			cout << pointer->num << endl;
    		else
    			cout << pointer->opr << endl;
    
    		pointer = pointer->next;
    	}//while
    
    }//printList
    
    /****************************************/
    //Converts an array of ints to a float value
    
    float arrayToFloat(char part[])
    {
    int L = 0, i, j;
    float val = 0, value[15] = {0};
    float valtab[5] = {1, 10, 100, 1000, 10000};
    //                 1   2   3     4     5
    
    	for(i = 0; part[i]; i++)
    	{
    		value[i] = part[i] - '0';//converting to int from char	
    	}//for
    	
    	L = strlen(part);
    	for(i = 0, j = L - 1; i < L; i++, j--)
    	{
    		val = val + (value[i] * valtab[j]);
    	}//for
    
    	return val;
    }//arrayToFloat

  15. #15
    Registered User
    Join Date
    Jul 2007
    Posts
    29
    Nevermind, figured out the problem.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  2. String sorthing, file opening and saving.
    By j0hnb in forum C Programming
    Replies: 9
    Last Post: 01-23-2003, 01:18 AM
  3. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM
  4. Strings are V important...
    By NANO in forum C++ Programming
    Replies: 15
    Last Post: 04-14-2002, 11:57 AM
  5. How do you search & sort an array?
    By sketchit in forum C Programming
    Replies: 30
    Last Post: 11-03-2001, 05:26 PM