存储从fgetc获取的字符

存储从fgetc获取的字符,c,assembly,C,Assembly,我正在做一项家庭作业,要求我删除汇编语言中的空格以及分号后的注释。例如mov%a,0x01;废话废话废话。我希望能够将所有字符存储在分号之前的数组中并打印它们。既然我是个傻瓜,你知道怎么做吗 #include <stdio.h> #include <ctype.h> #include <string.h> int main(int argc, char *argv[]) { char ch; int i; //char line[]

我正在做一项家庭作业,要求我删除汇编语言中的空格以及分号后的注释。例如
mov%a,0x01;废话废话废话
。我希望能够将所有字符存储在分号之前的数组中并打印它们。既然我是个傻瓜,你知道怎么做吗

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char ch;
    int i;
    //char line[] = "mov %a,0x01     ; system call number (sys_exit)\n";
    char label[100];
    char *infilename = argv[1];
    int length = strlen(line);

    FILE *infile = fopen(infilename, "rb");

    printf("         ");
    while (1) { 
        ch = fgetc(infile);
        if (ch == EOF)
            break;

        if (isspace(ch) == 0) {
            printf("%c", ch);               
        }
    }
    fclose(infile);
    return 0;
}
#包括
#包括
#包括
int main(int argc,char*argv[]){
char ch;
int i;
//字符行[]=“mov%a,0x01;系统呼叫号码(系统退出)\n”;
字符标签[100];
char*infilename=argv[1];
整数长度=strlen(直线);
文件*infile=fopen(infilename,“rb”);
printf(“”);
而第(1)款{
ch=fgetc(填充);
如果(ch==EOF)
打破
如果(isspace(ch)==0){
printf(“%c”,ch);
}
}
fclose(infle);
返回0;
}

ch
应定义为
int
,以便可以存储
EOF
值,并将其与文件结束前返回的所有
无符号字符
值区分开来

此外,行
int length=strlen(行)指未定义的变量

以下是一个更完整的版本:

#include <stdio.h>
#include <ctype.h>

int main(int argc, char *argv[]) {
    int ch, filter = 0, prefix = 1;
    char *infilename = argv[1];
    FILE *infile = fopen(infilename, "r");

    if (infile != NULL) {
        while ((ch = fgetc(infile)) != EOF) {
            if (prefix) {
                prefix = 0;
                printf("         "); // print the line prefix
            }
            if (ch == ';') { 
                filter = 1;   // filter characters until \n
            } else
            if (ch == '\n') {
                filter = 0;   // end of line: reset filter
                prefix = 1;   // and will print the prefix on next line
                putchar(ch);
            } else 
            if (!filter && !isspace(ch)) {
                putchar(ch);  // output character unless filtered          
            }
        }
        fclose(infile);
    }
    return 0;
}
#包括
#包括
int main(int argc,char*argv[]){
int ch,filter=0,prefix=1;
char*infilename=argv[1];
文件*infile=fopen(infilename,“r”);
if(infle!=NULL){
而((ch=fgetc(填充))!=EOF){
if(前缀){
前缀=0;
printf(“”;//打印行前缀
}
如果(ch==';'){
filter=1;//筛选字符直到\n
}否则
如果(ch='\n'){
筛选器=0;//行尾:重置筛选器
prefix=1;//并将在下一行打印前缀
putchar(ch);
}否则
如果(!filter&&!isspace(ch)){
putchar(ch);//输出字符,除非经过筛选
}
}
fclose(infle);
}
返回0;
}
注:

  • filter
    是一个布尔变量,用于确定是否应输出字符。默认情况下,
    filter=0
    ,因此字符将被输出,除非它们是空白。如果读取的字符是
    ,过滤器设置为
    1
    ,因此
    和以下字符将被过滤掉,直到行尾,而行尾未被过滤掉。此方案实现注释删除
  • prefix
    是一个布尔变量,设置在文件开头和每个换行之后,用于告诉循环在输出任何字符之前,在下一行开头输出
    ”。我从
    printf(“”)推断出您想要这种行为在代码中的循环之前,但它可能出于不同的目的而存在
  • 此简单筛选器可能不正确,因为它会删除所有空格字符,包括字符串文字中的空格字符。它还假定一个
    总是引入注释,但是
    不。。。您可能需要了解更多的程序集语法才能正确实现此筛选器

    • 一个简单的状态机:输入的文本是注释的一部分吗

      无需保存行,只需在行到达时打印即可

      bool IsComment = false;
      int ch;  // Insure to use type `int` for proper `EOF` compare and `isspace()` usage.
      while ((ch = fgetc(infile)) != EOF) {
        if (IsComment) {
          if (ch == '\n') {
            IsComment = false;
            fputc(ch, stdout); // end comment
          }
        } else if (isspace(ch) && ch != '\n') {
          ; // do not print space
        } else if (ch == ';') {
          IsComment = true;  // start comment
        } else {
          fputc(ch, stdout);
        }
      } 
      

      实际上不需要存储字符,您可以立即决定是否需要打印。@Jester您可能是对的,但在家庭作业方面,所需内容和要求之间往往存在差异。您需要删除
      %a、0x01
      之间的空格也是。但是将
      mov
      %a,0x01
      之间的空格限制为单个空格。有多种方法。但对于初学者来说,为什么不在出现
      时停止循环遇到字符?我建议使用
      fgets
      strtok
      。请注意,
      fgets
      将字符存储在一个数组中。
      ch
      必须是
      int
      ,才能执行
      EOF
      测试reliably@chqrlie同意
      ch
      需要是
      int
      ,因为在这个答案中,不仅是为了正确测试
      EOF
      ,而且也是为了便于携带
      isspace()
      。事实上,
      isspace()
      不应使用
      char
      参数调用。您好,感谢您的回复,您能否快速解释一下(iscomment)行是否为
      ';'
      开始一个类似于
      “废话废话”
      的注释,不应打印
      IsComment
      是一个标志,表示代码是读取注释文本还是常规文本。也许你的意思是
      ch
      而不是
      c
      ?@MichaelPetch:当然。。。我会选择
      c
      而不是
      ch
      ,我的手指也是。您好,谢谢您的详细回答,但您能解释一下过滤器和前缀的用法吗?@Jim:您能单击答案分数下面的灰色复选标记将其标记为已接受吗?