【问题标题】:Cannot change file name with system() in C (windows)无法使用 C 中的 system() 更改文件名(Windows)
【发布时间】:2018-02-12 09:54:51
【问题描述】:

我正在尝试使用 system() 命令获取 Windows PC 的 HDD 串行密钥,并将该数字保存在文本 (.txt) 文件中,文件名由用户选择。 system() 命令之前一切正常,但是 system() 命令没有更改文件名,也就是说,不是在用户选择之后命名文件,它只是在“contract_file_name”之后命名,没有扩展名。例如:如果我给出文件名: blahblah ,它应该创建一个名为“blahblah.txt”的文本文件(包含硬盘序列号),但它创建的是一个名为“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;
}

我能感觉到问题出在我的方法 system() 命令上,但是找不到任何解决方案。谁能建议我如何解决这个问题?

提前致谢。

【问题讨论】:

  • system() 函数不是命令提示符。它只运行程序,但不进行字符串替换和 I/O 重定向。
  • @iBug 谢谢,不知道,有什么替代建议吗?
  • @iBug 谁说它不做重定向?!它正在为 OP 重定向
  • @iBug: system 启动一个命令解释器,它实际上进行变量扩展和重定向。从技术上讲,OP 可以使用 putenv 并进行变量扩展。但是我强烈反对这样做。
  • @iBug, system 执行%ComSpec% /c [command line],这当然允许环境变量扩展和标准 I/O 重定向。我不知道你测试了什么导致你得出不同的结论。

标签: c windows file system


【解决方案1】:

您有 contract_file_name 是您的 system 调用中的文字字符串。您必须首先将变量的值放入字符串中,例如

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

您还应该将阅读到 contract_file_name 的内容限制为 99 个字符。

【讨论】:

  • 非常感谢,但请告诉我char tmp[_MAX_PATH+20 ]system(tmp)
  • tmpsprintf 创建的中间字符串的临时变量。长度必须足够长以包含所有字符。在您的情况下,contract_file_name 可以是 100 个字符长,我为字符串的其余部分添加了 20(这是错误的,它更像是 50)。在 Windows 中,通常使用 MAX_PATH 而不是 100 作为文件路径,这就是我首先编写 MAX_PATH 的原因。
  • 不工作...程序不断崩溃!!
  • 抱歉,我在sprintf 通话中忘记了tmp
  • 您最好使用snprintf 以获得更好的安全性。
【解决方案2】:

问题不在于system 函数(无论如何您都不应该将其用于此任务),而在于您误解了字符串替换的工作原理。

您有一个类型为“100 个字符的数组”的变量contract_file_name,并且显然希望字符串中每次出现的“contract_file_name”都会自动被替换。这称为“变量扩展”,实际上某些语言支持。最值得注意的是 shell 和 Perl。但是,您实际上必须在字符串中标记变量以进行替换(通常通过添加 $ 符号)。 这在 C 中不起作用! C 是一种非常节俭的语言,不具备该功能。

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

相反,您应该运行 wmicpopen。使用popenwmic 的输出被写入一个 FIFO,您可以直接读取它,就像它是一个文件一样,而无需将文件写入磁盘:https://msdn.microsoft.com/en-us/library/96ayss4b.aspx

【讨论】:

  • 但是我需要在磁盘中写入
  • @Md.FakruddinGazzaliFahim:然后你要么必须格式化(使用sprintf)一个适当的命令,或者这就是我推荐的,从popen-ed fifo读取并写入文件你fopen-ed;这就是系统调用中的&gt;&gt; 所做的。但是你自己这样做有好处,你不依赖于system启动的命令解释器的怪癖。
猜你喜欢
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 2021-03-20
  • 1970-01-01
  • 2011-07-12
  • 1970-01-01
相关资源
最近更新 更多