Scanf, sscanf, and fscanf do not directly support the field variable size specification.
You can however use tricks, as shown here .
The best solution however is to use fgets and calloc , and separate the fields manually.
These functions (scanf, fscanf, sscanf) are very fragile, in practice they are not used "in real life".
#include <stdio.h> // fgets, printf
#include <stdlib.h> // calloc
#include <string.h> // memcpy
int main()
{
// definicao dos tamanhos dos campos
int tamCpo1 = 3;
int tamCpo2 = 17;
int tamCpo3 = 3;
// definicao do tamanho do registro
int tamRegistro = tamCpo1 + tamCpo2 + tamCpo3;
// aloca memoria para os campos individuais
// soma 1 para zero binario no final
char* cpo1 = calloc(tamCpo1+1, 1);
char* cpo2 = calloc(tamCpo2+1, 1);
char* cpo3 = calloc(tamCpo3+1, 1);
// aloca memoria para o registro
// soma 2 para reservar espaco para \n#include <stdio.h> // fgets, printf
#include <stdlib.h> // calloc
#include <string.h> // memcpy
int main()
{
// definicao dos tamanhos dos campos
int tamCpo1 = 3;
int tamCpo2 = 17;
int tamCpo3 = 3;
// definicao do tamanho do registro
int tamRegistro = tamCpo1 + tamCpo2 + tamCpo3;
// aloca memoria para os campos individuais
// soma 1 para zero binario no final
char* cpo1 = calloc(tamCpo1+1, 1);
char* cpo2 = calloc(tamCpo2+1, 1);
char* cpo3 = calloc(tamCpo3+1, 1);
// aloca memoria para o registro
// soma 2 para reservar espaco para \n%pre%
char* registro = calloc(tamRegistro+2, 1);
// para computar tamanho do registro lido
int tamRegLido;
// arquivo a ser lido
FILE* arq;
// abre arquivo arq
arq = fopen("teste.txt", "r");
if (!arq)
{
printf("*\n");
printf("* arquivo 'teste.txt' inexistente\n");
printf("*\n");
exit(1);
}
printf("*\n");
// loop de leitura dos registros
for (;;)
{
// tenta ler um registro
if (!fgets(registro, tamRegistro+2, arq))
{
printf("*\n");
if (feof(arq))
printf("* fim de arquivo\n");
else
printf("* erro na leitura\n");
break; // sai do while
}
// ok, leu um registro
// computa o tamanho do registro lido
tamRegLido = strlen(registro);
if (tamRegLido < tamRegistro + 1)
{
printf("* ignorando registro com tamanho menor\n");
continue; // volta para inicio do while
}
if (registro[tamRegistro] != '\n')
{
printf("* ignorando registro com tamanho maior\n");
continue; // volta para inicio do while
}
// registro lido com tamanho correto
// separa os campos
memcpy(cpo1, registro, tamCpo1);
memcpy(cpo2, registro+tamCpo1, tamCpo2);
memcpy(cpo3, registro+tamCpo1+tamCpo2, tamCpo3);
// mostra os campos1 lidos
printf("* campo 1: [%s]\n", cpo1);
printf("* campo 2: [%s]\n", cpo2);
printf("* campo 3: [%s]\n", cpo3);
printf("*\n");
}
printf("*\n");
printf("* fim\n");
printf("*\n");
}
char* registro = calloc(tamRegistro+2, 1);
// para computar tamanho do registro lido
int tamRegLido;
// arquivo a ser lido
FILE* arq;
// abre arquivo arq
arq = fopen("teste.txt", "r");
if (!arq)
{
printf("*\n");
printf("* arquivo 'teste.txt' inexistente\n");
printf("*\n");
exit(1);
}
printf("*\n");
// loop de leitura dos registros
for (;;)
{
// tenta ler um registro
if (!fgets(registro, tamRegistro+2, arq))
{
printf("*\n");
if (feof(arq))
printf("* fim de arquivo\n");
else
printf("* erro na leitura\n");
break; // sai do while
}
// ok, leu um registro
// computa o tamanho do registro lido
tamRegLido = strlen(registro);
if (tamRegLido < tamRegistro + 1)
{
printf("* ignorando registro com tamanho menor\n");
continue; // volta para inicio do while
}
if (registro[tamRegistro] != '\n')
{
printf("* ignorando registro com tamanho maior\n");
continue; // volta para inicio do while
}
// registro lido com tamanho correto
// separa os campos
memcpy(cpo1, registro, tamCpo1);
memcpy(cpo2, registro+tamCpo1, tamCpo2);
memcpy(cpo3, registro+tamCpo1+tamCpo2, tamCpo3);
// mostra os campos1 lidos
printf("* campo 1: [%s]\n", cpo1);
printf("* campo 2: [%s]\n", cpo2);
printf("* campo 3: [%s]\n", cpo3);
printf("*\n");
}
printf("*\n");
printf("* fim\n");
printf("*\n");
}