15,311,717 members
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
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

## Solution 1

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
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

## Solution 2

I will do this in pseudo code...

C++
```int[] counters = new int[99];
string 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);
}```
Sergey Alexandrovich Kryukov 11-Jun-13 19:51pm

Sure, a 5.
—SA

## Solution 3

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]`.
Sergey Alexandrovich Kryukov 11-Jun-13 19:51pm

Sure, a 5.
—SA
CPallini 12-Jun-13 1:32am

Thank you.

## Solution 4

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
Sergey Alexandrovich Kryukov 11-Jun-13 19:51pm

Sure, a 5.
—SA
Espen Harlinn 12-Jun-13 15:50pm

Thank you, Sergey :-D