无法使用C(windows)中的system()更改文件名

无法使用C(windows)中的system()更改文件名,c,windows,file,system,C,Windows,File,System,我正在尝试使用system()命令获取windows PC的HDD序列键,并将该数字保存在一个文本(.txt)文件中,文件名由用户选择。在使用system()命令之前,一切都正常工作,但是system()命令没有更改文件名,也就是说,它不是按照用户的选择命名文件,而是按照“contract\u file\u name”命名,没有扩展名。例如:如果我给文件名:blahblah,它应该创建一个名为“blahblah.txt”(包含HDD序列键)的文本文件,但它创建的是一个名为“contract_fi

我正在尝试使用system()命令获取windows PC的HDD序列键,并将该数字保存在一个文本(.txt)文件中,文件名由用户选择。在使用system()命令之前,一切都正常工作,但是system()命令没有更改文件名,也就是说,它不是按照用户的选择命名文件,而是按照“contract\u file\u name”命名,没有扩展名。例如:如果我给文件名:blahblah,它应该创建一个名为“blahblah.txt”(包含HDD序列键)的文本文件,但它创建的是一个名为“contract_file_name”的文件

以下是代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char contract_file_name[100];
FILE *fp1 ;

filename:
printf("Please Give an APPROPRIATE name for SENDER-RECEIVER CONTRACT file. Please Don't use any .txt extension\nFILE NAME: ");
gets(contract_file_name);
strcat(contract_file_name,".txt");
if((fp1=fopen(contract_file_name,"r")))
    {
        printf("A Contract File with %s already EXITS.Please Choose another name\n".contract_file_name);
        goto filename;
    }
    else
    {

        fp1= fopen(contract_file_name,"w");
        fprintf(fp1,"$Sender: %s\n",getenv("USERNAME"));
        fclose(fp1);
        system("wmic path win32_physicalmedia get SerialNumber >> contract_file_name"); //Having problem in this line,I think.
        fp1 = fopen("contract_file_name","a");
        fprintf(fp1,"\n");
        fclose(fp1);
    }
return 0;
}
#包括
#包括
#包括
int main()
{
char contract_file_name[100];
文件*fp1;
文件名:
printf(“请为发送方-接收方合同文件提供适当的名称。请不要使用任何.txt扩展名\n文件名:”;
获取(合同文件名);
strcat(合同文件名“.txt”);
如果((fp1=fopen(合同文件名,“r”))
{
printf(“具有%s的合同文件已经存在。请选择另一个名称\n”。合同\u文件\u名称);
转到文件名;
}
其他的
{
fp1=fopen(合同文件名,“w”);
fprintf(fp1,“$Sender:%s\n”,getenv(“用户名”);
fclose(fp1);
系统(“wmic path win32\u physicalmedia get SerialNumber>>contract\u file\u name”);//我想这行有问题。
fp1=fopen(“合同文件名”,“a”);
fprintf(fp1,“\n”);
fclose(fp1);
}
返回0;
}
我能感觉到问题出在我的method system()命令上,但找不到任何解决方案。有人能建议我如何解决这个问题吗


提前谢谢

您有
合同文件\u name
系统调用中的一个文本字符串。您必须首先将变量的值放入字符串中,例如

char tmp[100+50];
sprintf(tmp, "wmic path win32_physicalmedia get SerialNumber >> %s",  contract_file_name);
system(tmp);

您还应该将对
合同文件名的读取限制为99个字符。

问题不在于
系统
函数(您无论如何都不应该使用该函数),而在于您误解了字符串替换的工作原理

您有一个类型为“array of 100 char”的变量
contract\u file\u name
,显然希望字符串中出现的每一个“contract\u file\u name”都会被自动替换。这称为“变量扩展”,实际上在某些语言中是受支持的。最著名的是shell和Perl。但是,您实际上必须在字符串中标记变量以进行替换(通常是在
$
符号前加上前缀)这在C中不起作用C是一种非常节俭的语言,没有这个功能

无论如何,您的程序会立即读回文件,因此使用固定的文件名或文件名是一个坏主意(想想如果您的程序的多个实例同时运行会发生什么情况;您能证明所有部分都是幂等的吗?可能不是)


相反,您应该使用
popen
运行
wmic
。使用
popen
wmic
的输出写入FIFO,您可以像读取文件一样直接读取,而无需将文件写入磁盘:

系统()
功能不是命令提示符。它只运行程序,但不执行字符串替换和I/O重定向。@iBug谢谢,我不知道,还有其他建议吗?@iBug谁说它不执行重定向?!它正在重定向到OP@iBug:
system
启动命令解释器,它实际上执行变量扩展和重定向。从技术上讲,OP可以使用
putenv
并进行变量扩展。但是我强烈反对这样做。@iBug,
system
执行
%ComSpec%/c[命令行]
,这当然允许环境变量扩展和标准I/O重定向。我不知道您测试的是什么导致您得出相反的结论。非常感谢,但请告诉我关于
char tmp[\u MAX\u PATH+20]
系统(tmp)
tmp
是由
sprintf
创建的中间字符串的临时变量。长度必须足够长,以包含所有字符。在您的例子中,
contract\u file\u name
可以是100个字符长,我为字符串的其余部分添加了20个字符(这是错误的,更像是50个字符)。在Windows中,文件路径通常使用MAX_PATH而不是100,这就是为什么我先编写MAX_PATH。不工作。。。程序不断崩溃!!对不起,我在
sprintf
调用中忘记了
tmp
。为了更好的安全性,你最好使用
snprintf
。但是我需要在disk@Md.FakruddinGazzaliFahim:然后您必须格式化(使用
sprintf
)一个适当的命令,或者,这就是我的建议,从
popen
-ed fifo读取数据,并将其写入您打开的文件中;这就是系统调用中的
>
所做的。但您自己这样做的好处是,您不必依赖于
系统启动的命令解释器的怪癖。