1

I am trying to read strings from a file and convert them to integers for storage in a struct. The strtol() function works well but removes any 0s from the start of the tokens. Is there any way I can keep them? The input file is formatted like the example below.

003345.755653
000046.003265
073532.003434
122280.065431

Input file ^^^

struct store{
int *age;
int *ref;
}rec[20];     

char *token;
char*ptr; 


    while (!feof (filea)){
        fgets(buffer, sizeof buffer, filea); 

        token = strtok(buffer, "."); 
        rec[count].age = malloc(10);
        rec[count].age = strtol(token, &ptr, 10);
        printf("Age:   %i\n", rec[count].age);

        token = strtok(NULL, ".");
        rec[count].ref = malloc(10);
        rec[count].ref = strtol(token, &ptr, 10);
        printf("Ref:          %i\n\n", rec[count].ref);
        count++;
        }
2
  • Step through your code in the debugger; it's not doing what you think it's doing. Commented Dec 11, 2014 at 18:56
  • What does the . in the file mean? Is it a decimal separator? If so, is it your plan to use two integers to store a single decimal number? Commented Dec 11, 2014 at 19:06

2 Answers 2

1

Once your string has been converted to an int or any other numeric type, all its leading zeros are gone, because they do not change the value of an integer.

You can add back leading zeros to get your numbers all have the same number of digits, but matching the exact number of leading zeros from a file would require additional storage.

Here is how you can format all your integers to two digits, with zero padding if necessary:

printf("Age:   %02i\n", rec[count].age);

Note: Your program has multiple errors. You need to fix them before it starts working properly.

  • You declare age and ref as pointers, but you use them like scalar variables
  • You allocate memory to age and ref using malloc, and then you override it with a numeric value
  • You ignore the new value of ptr after the read. You should use it to see if anything has been read from the file.

The compiler must have issued multiple warnings related to the issues described above. It is a good idea to treat all compiler warnings as errors, because it helps you find simple problems like these.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't know what ref means, but that . between the age and ref fields in the data file had me confused about whether we really are dealing with integers. If the OP is trying to use two integers to store one decimal value, then things are going to be a lot more complicated.
Looking at it another way, any number less than 1/2 of the max value for the type has leading zeros. Take the number 7 as a short, for example: 0000000000000111 in binary, or 0007 hex. We don't usually write the leading zeros when we express a number, but you can always prepend as many as you want.
0

No, you can't keep the zeros! The computer needs them - those are not growing on trees! No seriously: If you want to "keep" them long you'll just have to append the 0s in front of the printed of file-written strings.

You can use printf("%013.6f\n", a); where %0 means "append zeros" on a field of 13 units where 6 of them are after the decimal point.

#include <stdio.h>

int main()
{
    float a = 3345.755653;
    float b = 46.003265;
    float c = 73532.003434;
    float d = 122280.065431;

    printf("%013.6f\n", a);
    printf("%013.6f\n", b);
    printf("%013.6f\n", c);
    printf("%013.6f\n", d);

    return 0;
}

2 Comments

Sure your don't want printf("%013.4f\n"? (And float is likely too imprecise, suggest double or long double).
My float d resulted in 122280.062500, but double d --> 122280.065431.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.