C 调用System()后打印时的printf意外行为

C 调用System()后打印时的printf意外行为,c,windows,printf,C,Windows,Printf,我有以下带有相关控制台输出的“main”函数 argv[1] = "C:\\Program Files (x86)\\InstallShield Installation Information\\0x041f.txt" int main(int argc, char **argv){ if (argc < 2) { printf("Please provide a file name with extension\r\n"); retur

我有以下带有相关控制台输出的“main”函数

argv[1] = "C:\\Program Files (x86)\\InstallShield Installation Information\\0x041f.txt"

int main(int argc, char **argv){
    if (argc < 2)
    {
        printf("Please provide a file name with extension\r\n");
        return 1;
    }
    unsigned char buf[LEN_NORM];
    char filename[230];
    char ali_dirname[200];
    char bli_dirname[200];

    FILE *fp_obj, *fp_det, *fp_txt = fopen(argv[1], "rb");
    //dirty?
    *(argv[1] + strlen(argv[1]) + 1 - 5) = '\0';
    snprintf(ali_dirname, strlen(argv[1]) + 4, "%s/ali", argv[1]);
    snprintf(bli_dirname, strlen(argv[1]) + 4, "%s/bli", argv[1]);

    char cmd[200];
    snprintf(cmd, strlen(argv[1]) + 12, "@RD /S /Q \"%s\"", argv[1]);
    printf("cmd: %s\r\n", cmd);
    system(cmd);
    printf("cmd: %s\r\n", cmd);
}
argv[1]=“C:\\ProgramFiles(x86)\\InstallShield安装信息\\0x041f.txt”
int main(int argc,字符**argv){
如果(argc<2)
{
printf(“请提供扩展名为\r\n的文件名”);
返回1;
}
无符号字符buf[LEN_NORM];
字符文件名[230];
char ali_dirname[200];
char bli_dirname[200];
文件*fp_obj,*fp_det,*fp_txt=fopen(argv[1],“rb”);
//肮脏?
*(argv[1]+strlen(argv[1])+1-5)='\0';
snprintf(ali_dirname,strlen(argv[1])+4,“%s/ali”,argv[1]);
snprintf(bli_dirname,strlen(argv[1])+4,“%s/bli”,argv[1]);
char-cmd[200];
snprintf(cmd,strlen(argv[1])+12,“@RD/S/Q\%S\”,argv[1]);
printf(“cmd:%s\r\n”,cmd);
系统(cmd);
printf(“cmd:%s\r\n”,cmd);
}
cmd:@RD/S/Q“C:\Program Files(x86)\InstallShield安装信息\0x041f”

文件名、目录名或卷标语法不正确

更新信息\0x041f“ iles(x86)\InstallShield Installa

正如您在系统调用后所看到的,控制台已完全损坏。 我真的不明白为什么会发生这种事,知道吗

编辑: 感谢您的反馈,我认为snprintf length是关于要写入的数据长度。“cmd”有一个固定长度,这是允许的最大大小。根据我在网上找到的信息,“size”是将写入缓冲区的最大字节数(字符),因此在我的情况下,12应该是正确的数字(我用调试器检查了\“是否正确写入)而不是sizeof(cmd),我错了吗?在所有“snprintf”情况下,我都尝试过使用“12+1”(4+1)和“sizeof”,但没有任何变化

代码在“main”中运行(我已经更新了它)

如果我删除“系统(cmd)”调用,控制台输出正常!

  • 一个问题:一个接一个
strlen(argv[1])+12
是输出的预期长度,但它是应传递给
snprintf()
的所需大小-需要一个加号。在打印到
cmd
时,当前代码肯定会删除最后一个字符
“\”

//                                   12345678901   2
snprintf(cmd, strlen(argv[1]) + 12, "@RD /S /Q \"%s\"", argv[1]);
// better
snprintf(cmd, strlen(argv[1]) + 12 + 1, "@RD /S /Q \"%s\"", argv[1]);
这并不能很好地解释OP输出末尾的
\0x041f
,但肯定是个问题


  • 正确使用
    cmd
    的大小,最好在使用可能被截断的字符串执行系统命令之前测试结果

    int len = snprintf(cmd, sizeof cmd, "@RD /S /Q \"%s\"", argv[1]);
    if (len < 0 || (unsigned) len >= sizeof cmd) {
      fprintf(stderr, "Forming `cmd` failed\n");
    } else {
      printf("cmd: %s\r\n", cmd);
      system(cmd);
    }
    
    int len=snprintf(cmd,sizeof cmd,“@RD/S/Q\%S\”,argv[1]);
    如果(len<0 | |(无符号)len>=sizeof cmd){
    fprintf(stderr,“Forming`cmd`failed\n”);
    }否则{
    printf(“cmd:%s\r\n”,cmd);
    系统(cmd);
    }
    


未列出的代码中可能存在其他问题。

虽然这里不是这个问题,但是
snprintf()
的第二个参数应该是
sizeof(cmd)
。的第二个参数是目标缓冲区的大小,通常类似于
sizeof cmd
(在您的例子中)@LPs Hm,对于数组大小(通常以元素数量表示),您是对的,但我无法想象这样做对
snprintf()有什么好处
或一般的字符串函数……但是,它在course@LPs:绝对不适用于大小以字节为单位的内容,如
snprintf
。虽然通常不鼓励使用文本图像,但这是一个很好的问题示例,控制台窗口的屏幕截图会有所帮助。请拍摄““完全损坏”控制台窗口,并编辑您的问题以将其包括在内。在编辑问题时,请包括一个适当的参数,并告诉我们您传递给程序的确切参数(或者甚至可以硬编码
argv[1]
)。