Windows cmd 和 PowerShell 重定向到文件不起作用

问题描述

我有一个可执行文件,它接收一个文件作为参数,它厌倦了解析并将其转换为 ASM x86 (FLEX + YACC)。

问题是我正在尝试制作一个脚本来解析一堆文件并创建 ASM 输出文件,显然文件重定向不起作用,但将输出写入屏幕上。

使用 cmd:

.\mmlp.exe .\in\2.ps1

标准输出的结果:

bits 32
global start

; Needed procedures
extern exit,scanf,printf

; Imports
import exit msvcrt.dll
import scanf msvcrt.dll
import printf msvcrt.dll

; Data segment
segment data use32 class=data

    ; Format used by scanf & printf
    format_d db "%d",0

    ; Program's variables

    x dd 0
; Code segment
segment code use32 class = code
start:

    ; WRITE TO STDOUT
    push dword x
    push dword format_d
    call [printf]
    add esp,4 * 2

    ; exit(0)
    push dword 0
    call [exit]

但是如果我试试这个:

.\mmlp.exe .\in\2.ps1 > some-file.asm

文件将为空。

PowerShell 也是一样,尝试了不同的方法,都没有效果

& $exePath @($inFile) | Out-File some-file.asm
or
$result = & $exePath @($inFile)
or
& "cmd.exe" @("/c",$exeFile,$inFile,">","some-file.asm")

没有任何效果文件仍然是空的。 我什至尝试捕获所有输出流,但结果相同。

yacc文件中的主要功能如下:

int main(int argc,char **argv) {
    if (argc == 2) {
        yyin = fopen(argv[1],"r");
    }
    else {
        yyin = stdin;
    }

    asm_segment_data = malloc_list();
    asm_segment_code = malloc_list();

    int yyparse_result = yyparse();

    reverse_list(asm_segment_data);
    reverse_list(asm_segment_code);
    struct list_node *current;
    printf("%s%s",ASM_FILE_HEADER,ASM_SEGMENT_DATA);
    for(current = asm_segment_data->root; current != NULL; current = current->next) {
        printf("%s",current->value);
    }
    
    printf("%s",ASM_SEGMENT_CODE);
    for(current = asm_segment_code->root; current != NULL; current = current->next) {
        printf("%s",current->value);
    }

    printf("%s",ASM_EXIT);

    free_list(asm_segment_data);
    free_list(asm_segment_code);
    return yyparse_result;
}

基本上,我有一堆 printf 的。

我正在考虑提供第二个参数并写入该文件,但在某种程度上我更喜欢这种方法,因为它给了我更大的灵活性。 很明显,我做错了什么,但我看不出是什么。

更新:这是我编译可执行文件的方式(PowerShell):

$yaccFileNameFullPath = Join-Path -Path $WorkingDir -Childpath $YaccFileName
& "bison" @("-y","-d",$yaccFileNameFullPath)
$flexFileNameFullPath = Join-Path -Path $WorkingDir -Childpath $FlexFileName
& "flex" @($flexFileNameFullPath)
& "gcc" @("lex.yy.c","y.tab.c","-o",$exeFullPath)

更新 2:

我尝试了评论中推荐的所有内容,使用 fprintf(stdout...) 而不是 printf,但这没有用。文件的扩展名无关紧要,尝试了一堆。名称基本上只是一个单词和一个数字 [example1.extension]。

我最后只添加了另一个参数,它代表输出文件的路径。打开那个文件,用fprintf写入,还是什么都没有。

不知何故,我最终注释掉了这些行,这反过来又成功地完成了写入文件的操作。

    // free_list(asm_segment_data);
    // free_list(asm_segment_code);

free_list 函数

void free_list(struct list *list)
{
    struct list_node *current;
    for (current = list->root; current != NULL; current = current->next)
    {
        free(current);
    }

    free(list);
}

为什么最终会有内存泄漏?我知道我正在释放分配的字符数组,但是 printf/fprintf 不应该写一个副本吗?这段记忆是否有某种联系?刷新/关闭文件后我应该释放吗?

这就是我为 list_node 值分配内存的方式

#define ASM_FORMAT_ASSIGNMENT "\
    ; ASSIGNMENT\n\
    mov AX,[%s]\n\
    mov [%s],AX\n\n\
"

char *asm_assignment(char *from,char *to)
{
    char *buffer = (char *)malloc((strlen(ASM_FORMAT_ASSIGNMENT) +
                                   strlen(from) +
                                   strlen(to) + 1) *
                                  sizeof(char));
    sprintf(buffer,ASM_FORMAT_ASSIGNMENT,from,to);
    return buffer;
}

然后我在 YACC 文件中以匹配模式使用它,如下所示:

assignment          : ID ASSIGNMENT_OPERATOR operation {
                            memmove($1,$1 + 1,strlen($1)); // Remove '$' from variable name.
                            char *buffer = asm_assignment($3,$1);
                            printf("[mmlp.y] NEW ASM_ASSIGNMENT %s\n",buffer);
                            add_list(asm_segment_code,buffer);
                        }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)