string to smaller char array

Hi guys,

Have a very simple program here. The point is to start with a string which looks like a monetary value, then rip out all the digits, and put them into a char array. Finally convert the char array to double. My issue is regarding the second step, putting the digits from the string to the char array. I am not sure what I am doing wrong, but I keep getting weird symbols in console. I think it has to do with the null terminating character. Any help would be appreciated.

Thanks,

Mike

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <string>
#include <cctype>//library to use 'toupper', 'tolower'....
#include <vector>
#include <fstream>
using namespace std;
using std::ifstream;
using std::ofstream;
using std::endl;
using std::ios;

const int MAX=100;



int main()
{	
	char choice;
	string first="123,456,789";
	char last[MAX];
	int i, count=0;

	int length=first.length();
	do
	{
		
		for(i=0;i<length;i++)
		{
			if(isdigit(first[i]))
				last[i]=first[i];
			if(first[i]==',')
				count++;
		
		}
		cout<<"count is: "<<count<<endl;
		last[length-count]='\0';
		cout<<"Last is: "<<last<<endl;
		cout<<endl<<endl;
		cout<<"Again(y/n): ";
		cin>>choice;
	}while(choice=='y');

	_getch();
}




This is because whenever it finds a "," you are still treating it as character..

1 is stored in the last[0]
2 is stored in last[1]
3 is stored in last[2]
, is not stored, so last[3] is empty .. ( or could contain a random char as you didn't empty the store on declaration).
4 is stored in last [4]
etc..

this creates a hole. Instead you could have a seperate counter for last. Like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{	
	char choice;
	string first="123,456,789";
	char last[MAX]= {NULL};
	int i,j, count=0;
	int length=first.length();
	do
	{
		
		for(i=0, j=0;i<length;i++)
		{
			if(isdigit(first[i]))
				last[j++]=first[i];
			if(first[i]==',')
				count++;
            
		}
		cout<<"count is: "<<count<<endl;
		last[length-count]='\0';
		cout<<"Last is: "<<last<<endl;
		cout<<endl<<endl;
		cout<<"Again(y/n): ";
		cin>>choice;
	}while(choice=='y');
    
}


count is: 2
Last is: 123456789


Again(y/n): n
1
2
3
4
5
6
7
for(i=0;i<length;i++)
{
	if(isdigit(first[i]))
		last[i]=first[i];
	if(first[i]==',')
		count++;
}


You put the character to the same position in last as they are in the first. last[3] and last[7] will contain undefined values because you don't write anything to those positions. Maybe you can use count to adjust the position to write to in last.
Last edited on
I see what you guys are talking about, and now I understand. Thanks a lot for the advice, I have been tinkering with this all morning!

Mike
Sorry one more question, the book I am going through right now (about 10 years old) does not use "char last[MAX]= {NULL}." Is this something new that's cropped up, is this just considered good style?

What's the point of the {NULL}?
What is written inside { here } is the values to initialize the elements in the array to.

char last[MAX]= {'a', 'b', 'c'};
This will initialize the first element to 'a', the second element to 'b' and the third element to 'c'. The rest of the elements will be initialized to '\0'.

NULL is 0 **. 0 converted to a char is the same as '\0', so
char last[MAX]= {NULL};
will just initialize all the elements in the array to '\0'.
char last[MAX]= {};
would have done the same thing.

If you define the array as just
char last[MAX];
all the elements are uninitialized.

One advantage with initializing all the elements to '\0' is that you don't have to care about putting '\0' at the end of the string as you do on line 20.

** NULL is meant to be used as a null pointer so I would not consider it good style to use it as a char value. In C++11 NULL can be defined as nullptr and in that case using NULL here would not even compile.
Last edited on
What I did here is called an aggregate initialization.

When you create an object that’s an aggregate, all you must do is make an assignment, and the initialization will be taken care of by the compiler.

for a built-in type it can be as simple as this:
int a[5] = { 1, 2, 3, 4, 5 };

However, if you initialize only the first element, the remaining elements fill automatically be filled with zero-values.

Basically what I did is initialize the first element with NULL. The compiler will fill the rest with zero-values.

The "NULL" is in fact optional. I find it more convenient for several reasons, but just typing int a[5] = {}; will do the same.

So basically I tell the compiler to clean the space that is allocated to last[max]. If you leave this out you could end up with undefined values. Allocating storage for a variable doesn't automatically empty the storage.
The reason is probably for efficiency. If you're going to fill each element in the array it serves no purpose to clean it.

In the progress of finding your bug, I noticed the undefined values and choose to empty them.
You can leave out that part of the code, now that the bug is traced.
Last edited on
Yes, that answers my question.

Thanks a lot guys!
Topic archived. No new replies allowed.