[英]How to properly use fscanf to store only the needed information in an array?
I'm trying to write a program in c that reads a mtx file (mtx stands for midi to text, it's actually a txt file) and stores only the information I need (specifically only the note-on/off and pitch-bend messages) here's an example:我正在尝试用 c 编写一个程序来读取 mtx 文件(mtx 代表 midi 到文本,它实际上是一个 txt 文件)并仅存储我需要的信息(特别是仅音符开/关和弯音消息) 这是一个例子:
the information that I need are: the timing (first number), the type (On, Off and Pb), the "n=" value and the "v=" value (in pitch-bend messages there's only the "v=" value).我需要的信息是:时间(第一个数字)、类型(开、关和铅)、“n=”值和“v=”值(在弯音消息中只有“v=”价值)。 I'm not an expert in C language, I know the basics and I based my programming on this guide and this guide .我不是 C 语言专家,我知道基础知识,我的编程基于本指南和本指南。
Here's the code I wrote:这是我写的代码:
FILE * read_from;
char status[3];
int u = 0;
int ctrl,ct;
read_from = fopen(nomesong, "r");
if (!read_from)
printf("NO WAY\n");
else{
while (1){
ct = fscanf(read_from, "%d", array[u][0]);
if (ct == 1){
ctrl = fscanf(read_from, " %s", &status);
if (ctrl == 1){
if (status[1] == 'n'){
array[u][1] = 1;
fscanf(read_from, " ch=1 n=%d v=%d", array[u][2], array[u][3]);
}
else if (status[1] == 'f'){
array[u][1] = 0;
fscanf(read_from, " ch=1 n=%d v=%d", array[u][2], array[u][3]);
}
else if (status[1] == 'b'){
array[u][1] = 2;
fscanf(read_from, " ch=1 v=%d", array[u][3]);
}
}
else if (errno != 0) {
perror("scanf:");
break;
}
else {
printf("No match.\n");
}
}
else if (errno != 0) {
perror("scanf:");
break;
}
else if (ctrl == EOF) {
break;
}
printf("%d %d %d %d\n", array[u][0], array[u][1], array[u][2], array[u][3]);
u++;
}
}return;
As output it prints four zeros per row (array[][] is initialized to 0) then starts spewing out random big numbers, then keeps printing zeros and then stops and VS (2013) emits the "Unhandled exeption" alert message.作为输出,它每行打印四个零(array[][] 初始化为 0)然后开始喷出随机大数字,然后继续打印零然后停止,VS(2013)发出“未处理的例外”警报消息。 What am I doing wrong?我究竟做错了什么? Any help will be appreciated.任何帮助将不胜感激。
OP's code problems include: OP的代码问题包括:
1) Passing a variable, rather than an address of a variable in fscanf(read_from, " ch=1 n=%dv=%d", array[u][2], array[u][3]);
1) 传递一个变量,而不是fscanf(read_from, " ch=1 n=%dv=%d", array[u][2], array[u][3]);
2) Insufficient space reading "Off"
with char status[3]; ... ctrl = fscanf(read_from, " %s", &status);
2) 空间不足,读取"Off"
并带有char status[3]; ... ctrl = fscanf(read_from, " %s", &status);
char status[3]; ... ctrl = fscanf(read_from, " %s", &status);
The better approach is to not use fscanf()
.更好的方法是不使用fscanf()
。 Read the line using fgets()
or getline()
and then scan using sscanf()
, strtol()
, etc.使用fgets()
或getline()
读取该行,然后使用sscanf()
、 strtol()
等进行扫描。
// Read line by line until EOF
while (fgets(buf, sizeof buf, read_from)) {
// Clear entry
memset(&array[u], 0, sizeof (array[u]));
if (3 == sscanf(buf, "%d Off ch=1 n=%d v=%d",
&array[u][0], &array[u][2], &array[u][3])) {
array[u][1] = 1;
} else if (3 == sscanf(buf, "%d On ch=1 n=%d v=%d",
&array[u][0], &array[u][2], &array[u][3])) {
array[u][1] = 0;
} else if (2 == sscanf(buf, "%d Pb ch=1 v=%d",
&array[u][0], &array[u][3])) {
array[u][1] = 2;
}
Note: as ch=1
is likely not a constant 1
, code could use "%*d"
to scan and discard the ch
number.注意:由于ch=1
可能不是常数1
,代码可以使用"%*d"
来扫描并丢弃ch
数。
if (3 == sscanf(buf, "%d Off ch=%*d n=%d v=%d",
&array[u][0], &array[u][2], &array[u][3])) {
array[u][1] = 1;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.