Click here to Skip to main content
15,311,717 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
Hi Everyone,
Following on from a previous thread... I have been given code that I need to convert to be able to read in a program. One of the main problems is that the primary field I have to convert has 6 characters and I need to convert it to 4 characters, obviously unique. The 6 characters are divided into groups of 2, each group means something, however the first group is the one with the most useful informaton.

Example:
102030
10 is the useful field
20 is just descriptive
30 is just descriptive

Some examples are:
107011
151030
151070
152930
152970
171030
171070
141030
111030
111070
201030
201070

To convert the above to 4 characters instead of 6 I have devised a plan to keep the first 2 characters, but increment the 2nd two until it hits a new number.
Eg:
107011
151030 will be 151
151070 will be 152
152930 will be 153
152970 will be 154
171030 will be 171

The problem I have is that some of them have more than 99 items. Using the above examples and assuming I have 99 number 15's, the last one will be 1599 and the one after will be 15100..which is 5 characters. I therefore thought I could come up with an alphanumeric option. Eg: 15A1, 15A2....15A9, 15B1....15B9, 15C1...15C9, etc. This means I can go up to 26 * 9 = 234 items per number. My problems is...I have no idea how to do it. My current code snippet is as follows:

C++
#include <stdAfx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <conio.h>
int main()
{ 
	//
	char line[200];
	long i, j, k, n10, n20, n30, n40, n50, n60, l10, l20, l30, l40, l50, l60;
	long NodeName;
	double x, y, z;
	//
	n10 = 0; n20 = 0; n30 = 0; n40 = 0; n50 = 0; n60 = 0;
	l10 = 10; l20 = 20; l30 = 30; l40 = 40; l50 = 50; l60 = 60;
	FILE *pFile, *OutPut;    
	pFile = fopen("Input.txt", "r");   
	if( (OutPut = fopen("Output.inp", "w" )) != NULL )
	{
	}
	else
	{printf( "Problem creating Output file\n");}
	//fgets gets a string from a file//one string per line  
	while(fgets(line, sizeof line, pFile) != NULL)    
	{
	
		if(sscanf_s(line, "%d %lf %lf %lf", &NodeName, &x, &y, &z) == 4)    
			
		{    
			//Each case below populates the Nodename field with the first two numbers of the 6 character input nodename and then increments for the following two numbers up until new number is reached.
			j = NodeName / 10000;
			if(j < 20 )
			{
				if( j > l10)
				{
					l10 = j;
					n10 = 0;
				}
				n10 += 1;
				fprintf(OutPut,"%2d", l10);
				fprintf(OutPut,"%2d ", n10);
				goto skp;
			}
			if(j < 30)
			{
				if( j > l20)
				{
					l20 = j;
					n20 = 0;
				}
				n20 += 1;
				fprintf(OutPut,"20");
				fprintf(OutPut,"%2d ", n20);
				goto skp;
			}
			if(j < 40)
			{
				if( j > l30)
				{
					l30 = j;
					n30 = 0;
				}
				n30 += 1;
				fprintf(OutPut,"30");
				fprintf(OutPut,"%2d ", n30);
				goto skp;
			}
			if(j < 50)
			{
				if( j > l40)
				{
					l40 = j;
					n40 = 0;
				}
				n40 += 1;
				fprintf(OutPut,"40");
				fprintf(OutPut,"%2d ", n40);
				goto skp;
			}
			/*			k = (NodeName[i] - 10000 * j) / 10;
			fprintf(OutPut,"%3d ", k);*/
skp:;
Posted
Comments
max_nowak 3-May-13 8:53am
   
And what are you doing when you got 235 ids starting with prefix '15'? I think you should contemplate if you really need to have the 'useful field' unqiue in the first place. Why not mapping a hash value to each of it or something?
Member 9357265 3-May-13 9:16am
   
I generally have about 130 - 150 id's so 235 will be fine. The "useful" field does mean something, it is level in an engineering structure so ideally would like to keep the first two characters

Yes, go with "the alpha-numeric option" - i.e. how about hexadecimal!?
Use %x (or %X) in exactly the same way you would use %d (i.e. you can zero pad, etc) for outputting the value - you probably want to use "%02X"
This will mean that you can go up to 0xFF numbers (255).

Regards,
Ian.
   
v2
Comments
Member 9357265 3-May-13 9:18am
   
As commented above..The "useful" field does mean something, it is level in an engineering structure so need to keep it in it's current readable form. I can increment using the other two fields...hence the alphanumeric decision.
Member 9357265 3-May-13 9:22am
   
Sorry, after re-reading and engaging my brain I get what you are saying...up to 255 I can get up to 2 digit hex numbers..(essentially type of alphanumeric I suppose).I will try and let you know. thanks...
Ian A Davidson 3-May-13 11:16am
   
Yes. (You could even possibly start at zero, so you would have 256 permutations). so using your example you would have: 151030 will be 1500 151070 will be 1501 152930 will be 1502 152970 will be 1503 171030 will be 1701 etc. So if you had a lot of 15xxxx, your new numbers would run from 1500 to 15FF. Regards, Ian.
   
It's actually a very good alternatives, to use hex, as hex numerals are more readable, aren't they? :-) My 5.
—SA
Ian A Davidson 3-May-13 17:31pm
   
It seemed to make sense. Thank you SA. :)
Member 9357265 6-May-13 5:00am
   
This is working a treat... just replaced
fprintf(OutPut,"%2d ", n10);
with
fprintf(OutPut,"%02lX", n10);
for all the cases and it works. Thanks
I will do this in pseudo code...

C++
int[] counters = new int[99];
string line;

while (ReadLine(line))
{
    //You only care about the first two characters, so that's all you look at...
    string num = line[0] + line[1];

    int inum = strtoi(num);

    string outnum = num + itohex(counters[inum]);  //Convert the integer to hex, 2 digits
    counters[inum]++;

    WriteOut(outnum);
}
   
Comments
Sergey Alexandrovich Kryukov 11-Jun-13 19:51pm
   
Sure, a 5.
—SA
Quote:
This means I can go up to 26 * 9 = 234 items per number

That's wrong, using just (two) A..Z letters you have 26^2=26*26=676 items.

Quote:
My problems is...I have no idea how to do it.


The simplest way would be using an array, e.g.
C
char code[26] = {'A', 'B', 'C', 'D', /* ... */, 'Z'}; // there are more clever ways to do this


then the two letter suffix of yor nth code would be given by code[n/26] and code[n%26].
   
Comments
Sergey Alexandrovich Kryukov 11-Jun-13 19:51pm
   
Sure, a 5.
—SA
CPallini 12-Jun-13 1:32am
   
Thank you.
There is no reason to implement this yourself, and you are making this way more difficult than you need to:

atoi[^]

itoa[^] - Just use a higher base, 16 would be hex.

Best regards
Espen Harlinn
   
Comments
Sergey Alexandrovich Kryukov 11-Jun-13 19:51pm
   
Sure, a 5.
—SA
Espen Harlinn 12-Jun-13 15:50pm
   
Thank you, Sergey :-D

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900