C 调用System()后打印时的printf意外行为
我有以下带有相关控制台输出的“main”函数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
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]
)。