将fscanf与while循环一起使用以存储char和int

时间:2018-11-12 01:52:28

标签: c while-loop scanf

我正在尝试使用fscanf来读取一个十六进制数字文件,该文件具有一个字符,后面跟一个数字,或者只有数字而没有字符。 fscanf似乎适用于文件的第一行,仅此而已。

文件

E10
20
22
18
E10
210
12

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;

iFile = fopen("addresses.txt", "r");
if(iFile != NULL){

    while (fscanf(iFile, "%c%x", &instr, &address) > 0){

      printf("%c", instr);   //This just works for the first line

    }

}
fclose(iFile);
return 0;
}

1 个答案:

答案 0 :(得分:0)

在这种情况下,您将尝试多次分析同一行,最好将行读入内存,然后处理内存中的数据,而不是磁盘上的数据。

char line[MAXLINE];
fgets(line, MAXLINE, iFile);

然后您拥有我所谓的“ sscanf阶梯”,它是一系列if-else if子句,每个子句都尝试以不同的方式解析line。该条件将检查sscanf的返回值,因为成功读取的对象数是返回值。因此,我们使用此数字来区分几种不同的格式:

if (sscanf(line, "%c%x", &instr, &address) == 2)
    /* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
    /* you have an address only */

因为在您的情况下,这是一个循环条件,所以您必须将其重构为自己的功能:

int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
    return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}

然后您将这样重写循环

while (readAtLeastAddress(line, &instr, &address)) {
    printf("%c", instr);
}