将一行的前三个字符串读入单独的数组,然后将该行的其余部分读入 C 中的第四个字符串?
Read the first three strings of a line into individual arrays, then read the rest of the line into a fourth string in C?
我正在用 C 编写汇编程序的第一遍以进行赋值,需要读取包含汇编代码的文本文件行,并将标签、操作码和操作数以及任何注释存储在前三个字符串之后的行。我最初使用
fscanf(fileptr1,"%s\t%s\t%s",label,opcode,operand);
对于没有注释的文件,但 sscanf 无法将行的其余部分放入单个字符数组中。似乎我会使用 fgets
,但我如何将它分成前三个字符串,用空格分隔,然后是该行的其余部分,直到换行符?
作为参考,各行遵循以下格式:
LABEL OPCODE OPERAND COMMENTS IN MULTIPLE STRINGS
我想要单独字符串中的标签、操作码和操作数,就像我现在所做的那样,然后是一个单独的字符串用于整个行的其余部分。汇编代码中的几行供参考:
COPY START 1000 COPY FILE FROM INPUT TO OUTPUT
FIRST STL RETADR SAVE RETURN ADDRESS
CLOOP JSUB RDREC READ INPUT RECORD
LDA LENGTH TEST FOR EOF (LENGTH = 0)
COMP ZERO
JEQ ENDFIL EXIT IF EOF FOUND
JSUB WRREC WRITE OUTPUT RECORD
J CLOOP LOOP
为每个字段定义特定的分隔符
fscanf( fileptr1, "%[^\t] %[^\t] %[^\t] %[^\n]", label, opcode, operand, comment ) ;
您或许应该添加字段宽度说明符并检查 return 值,以检查错误和超限,但这是一个不同的问题。
但还有其他方法。例如,您可以 fgets()
将整行放入一个数组,然后使用 strtok()
将其拆分,使用 \t
作为分隔符。
char line[1024] = {0} ;
fgets( line, sizeof(line), fileptr1 ) ;
char* label = strtok( line, "\t" ) ;
char* opcode = label != 0 ? strtok( 0, "\t" ) : 0 ;
char* operand = opcode != 0 ? strtok( 0, "\t" ) : 0 ;
char* comment = operand != 0 ? strtok( 0, "\n" ) : 0 ;
第 1 步:阅读带有 fgets()
的行
char buffer[256];
while (fgets(buffer, sizeof buffer,fileptr1) {
how would I separate that into the first three strings separated by whitespace, ...
这是对问题的错误评估。在第一个 "string" 或 label
为空的 " LDA LENGTH TEST FOR EOF (LENGTH = 0)"
的情况下,3 "strings" 没有被空格分隔。
相反,代码需要查找缺失的字段。
第 2 步:有多种方法:下面是 try-it-1-of-2 方法,具体取决于前导字符是否为 white-space。通过测试 n
测试扫描是否成功
char label[8];
char opcode[8];
char operand[12];
char comment[sizeof buffer]; // big enough to handle the rest of the line
label[0] = '[=11=]';
opcode[0] = '[=11=]';
operand[0] = '[=11=]';
comment[0] = '[=11=]';
int n = 0;
if (isspace((unsigned char) buffer[0])) {
// vv--------- Save offset of scan if we got that far
sscanf(buffer, "%7s%11s %n" , opcode, operand, &n);
} else {
sscanf(buffer, "%7s%7s%11s %n" , label, opcode, operand, &n);
}
if (n == 0) {
// Handle bad input with TBD code
continue;
}
// look for comment starting at `n`
if (buffer[n]) {
// scan in comment
sscanf(buffer + n, "%[^\n]" , comment);
}
// do something with input
printf("<%s> <%s> <%s> <%s>\n", label,opcode,operand,comment);
}
代码可以测试 "too long" 和 label,opcode,operand
。示例:
// Assume max length of opcode == 7
char opcode[7 + 1 + 1]; // +1 for extra, +1 for null character
...
sscanf(..., "...%8s...", .... opcode ...);
if (opcode[7 + 1]) Handle_TooLoong();
我正在用 C 编写汇编程序的第一遍以进行赋值,需要读取包含汇编代码的文本文件行,并将标签、操作码和操作数以及任何注释存储在前三个字符串之后的行。我最初使用
fscanf(fileptr1,"%s\t%s\t%s",label,opcode,operand);
对于没有注释的文件,但 sscanf 无法将行的其余部分放入单个字符数组中。似乎我会使用 fgets
,但我如何将它分成前三个字符串,用空格分隔,然后是该行的其余部分,直到换行符?
作为参考,各行遵循以下格式:
LABEL OPCODE OPERAND COMMENTS IN MULTIPLE STRINGS
我想要单独字符串中的标签、操作码和操作数,就像我现在所做的那样,然后是一个单独的字符串用于整个行的其余部分。汇编代码中的几行供参考:
COPY START 1000 COPY FILE FROM INPUT TO OUTPUT
FIRST STL RETADR SAVE RETURN ADDRESS
CLOOP JSUB RDREC READ INPUT RECORD
LDA LENGTH TEST FOR EOF (LENGTH = 0)
COMP ZERO
JEQ ENDFIL EXIT IF EOF FOUND
JSUB WRREC WRITE OUTPUT RECORD
J CLOOP LOOP
为每个字段定义特定的分隔符
fscanf( fileptr1, "%[^\t] %[^\t] %[^\t] %[^\n]", label, opcode, operand, comment ) ;
您或许应该添加字段宽度说明符并检查 return 值,以检查错误和超限,但这是一个不同的问题。
但还有其他方法。例如,您可以 fgets()
将整行放入一个数组,然后使用 strtok()
将其拆分,使用 \t
作为分隔符。
char line[1024] = {0} ;
fgets( line, sizeof(line), fileptr1 ) ;
char* label = strtok( line, "\t" ) ;
char* opcode = label != 0 ? strtok( 0, "\t" ) : 0 ;
char* operand = opcode != 0 ? strtok( 0, "\t" ) : 0 ;
char* comment = operand != 0 ? strtok( 0, "\n" ) : 0 ;
第 1 步:阅读带有 fgets()
char buffer[256];
while (fgets(buffer, sizeof buffer,fileptr1) {
how would I separate that into the first three strings separated by whitespace, ...
这是对问题的错误评估。在第一个 "string" 或 label
为空的 " LDA LENGTH TEST FOR EOF (LENGTH = 0)"
的情况下,3 "strings" 没有被空格分隔。
相反,代码需要查找缺失的字段。
第 2 步:有多种方法:下面是 try-it-1-of-2 方法,具体取决于前导字符是否为 white-space。通过测试 n
char label[8];
char opcode[8];
char operand[12];
char comment[sizeof buffer]; // big enough to handle the rest of the line
label[0] = '[=11=]';
opcode[0] = '[=11=]';
operand[0] = '[=11=]';
comment[0] = '[=11=]';
int n = 0;
if (isspace((unsigned char) buffer[0])) {
// vv--------- Save offset of scan if we got that far
sscanf(buffer, "%7s%11s %n" , opcode, operand, &n);
} else {
sscanf(buffer, "%7s%7s%11s %n" , label, opcode, operand, &n);
}
if (n == 0) {
// Handle bad input with TBD code
continue;
}
// look for comment starting at `n`
if (buffer[n]) {
// scan in comment
sscanf(buffer + n, "%[^\n]" , comment);
}
// do something with input
printf("<%s> <%s> <%s> <%s>\n", label,opcode,operand,comment);
}
代码可以测试 "too long" 和 label,opcode,operand
。示例:
// Assume max length of opcode == 7
char opcode[7 + 1 + 1]; // +1 for extra, +1 for null character
...
sscanf(..., "...%8s...", .... opcode ...);
if (opcode[7 + 1]) Handle_TooLoong();