17

I am trying to read in a certain portion of a file and that amount of data is different per line but I know how how many bytes of info I want. Like this:

5bytes.byte1byte2byte3byte4byte5CKSum //where # of bytes varies for each line (and there is no period only there for readability)  

Actual data:

05AABBCCDDEE11
03AABBCC22
04AABBCCDD33

So I want to have my width be a variable like this:

fscanf_s(in_file,"%variableX", &iData);  

Is this possible, because right now I'm thinking I have to create a case statement?

Naftali
  • 144,921
  • 39
  • 244
  • 303
Nick Sinas
  • 2,594
  • 11
  • 42
  • 51
  • 1
    You need to clarify what you're asking. – Amardeep AC9MF Jul 22 '10 at 21:01
  • basically i just want to be able to set the width with a variable that I can change per every line I read instead of "%5X"-here I am limited to a width of 5, I just want to put my own variable in there so my width can be dynamic. – Nick Sinas Jul 22 '10 at 21:23

5 Answers5

17

Unfortunately, no, there's no modifier like '*' for printf that causes scanf to get its field width or precision from a variable. The closest you can come is dynamically creating the format string:

char format[8];
sprintf(format, "%%%dX", width);
fscanf(in_file, format, &iData);
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
2

If you really want to be able to adjust the fscanf format programmatically, you could try stack-allocating a string with enough space, and then generating the format like so: e.g.

char formatString[100];

// writes "%max_size[0-9]", substituting max_size with the proper digits
sprintf(formatString, "%%%d[0-9]", MAX_SIZE); 

fscanf(fp, formatString, buffer); // etc...
Rose Perrone
  • 61,572
  • 58
  • 208
  • 243
0

fscanf with %X will stop at a newline automatically, right? If the fields really are newline-terminated (as in your example), then can't you just call

fscanf(in_file, "%X", &iData);

and let fscanf figure out where the end is?

SCFrench
  • 8,244
  • 2
  • 31
  • 61
  • Yes thats right I actually made a mistake there is a checksum at the end that I don't want. So this wouldnt work for me. – Nick Sinas Jul 22 '10 at 22:18
0

You might also consider using C++ streams.

#include <ifstream>
#include <iostream>

// open the file and create a file input stream
ifstream file("test.txt" , ios::in | ios::binary);

// loop through the whole file
while (ifs.good())
{
    // extract one byte as the field width
    unsigned char width;
    file.read(&width, 1);

    // extract width number of unformatted bytes
    char * bytes = new char[width];
    file.read(bytes, width);

    // process the bytes
    ...
    delete [] bytes;

    // skip EOL characters if needed
    // file.seekg(1, ios_base::cur)
}

file.close();

A simpler way if the newlines are included as you seem to indicate, would be to use getLine(). Check out http://www.cplusplus.com/reference/iostream/ifstream/ for more ways to use read(), get(), getLine() and lots of other great stream functions.

gnathan
  • 254
  • 1
  • 3
  • 14
0

I think the simplest would be to use fread() like this:

fread(buffer, nbytes, sizeof(char), in_file);
ahy1
  • 368
  • 1
  • 5