C Visual Studio文件输出错误

C Visual Studio文件输出错误,c,eclipse,visual-studio-express,C,Eclipse,Visual Studio Express,当我在eclipse上构建下面的代码时,命令行中的所有内容都按照预期工作,输出文件中的所有内容看起来都与预期一样 #include <stdio.h> #include <stdlib.h> // for exit() #include <string.h> int main(int argc, char *argv[]) { FILE *in, *out; // declare two FILE pointers int ch; // check for c

当我在eclipse上构建下面的代码时,命令行中的所有内容都按照预期工作,输出文件中的所有内容看起来都与预期一样

#include <stdio.h>
#include <stdlib.h> // for exit()
#include <string.h>
int main(int argc, char *argv[])
{
FILE *in, *out; // declare two FILE pointers
int ch;
// check for command-line arguments
if (argc < 2)
{
    fprintf(stderr, "Usage: %s filename\n", argv[0]);
    exit(EXIT_FAILURE);
}
// set up input
if ((in = fopen(argv[1], "r")) == NULL)
{
    fprintf(stderr, "I couldn't open the file \"%s\"\n",
        argv[1]);
    exit(EXIT_FAILURE);
}
// set up output
char *ptd;
ptd = (char*)malloc(150 * sizeof(char));
char x;
int i = 0;
while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;
}
ptd[i + 1] = '\0';
strcat(ptd, ".txt"); // append .txt
if ((out = fopen(ptd, "w")) == NULL)
{ // open file for writing
    fprintf(stderr, "Can't create output file.\n");
    exit(3);
}
// copy data
while ((ch = getc(in)) != EOF)
        putc(ch, out); // print every 3rd char
// clean up
if (fclose(in) != 0 || fclose(out) != 0)
    fprintf(stderr, "Error in closing files\n");
free(ptd);
return 0;
}
#包括
#包含//用于退出()
#包括
int main(int argc,char*argv[])
{
FILE*in,*out;//声明两个文件指针
int-ch;
//检查命令行参数
如果(argc<2)
{
fprintf(stderr,“用法:%s文件名\n”,argv[0]);
退出(退出失败);
}
//设置输入
if((in=fopen(argv[1],“r”)==NULL)
{
fprintf(stderr,“我无法打开文件\%s\”\n),
argv[1]);
退出(退出失败);
}
//设置输出
字符*ptd;
ptd=(char*)malloc(150*sizeof(char));
字符x;
int i=0;
而((x=getchar())!='\n'){
ptd[i]=x;
i++;
}
ptd[i+1]='\0';
strcat(ptd,“.txt”);//append.txt
if((out=fopen(ptd,“w”))==NULL)
{//打开文件进行写入
fprintf(stderr,“无法创建输出文件。\n”);
出口(3);
}
//复制数据
而((ch=getc(in))!=EOF)
putc(ch,out);//每三个字符打印一次
//清理
如果(fclose(in)!=0 | | fclose(out)!=0)
fprintf(stderr,“关闭文件时出错\n”);
免费(ptd);
返回0;
}

但是当我用VisualStudio构建它时,我会在我的文件名后面加上这个“Í”,直到它到达.txt,它会使用所有分配的内存作为文件名。为什么会发生这种情况?

您没有正确终止字符串:

while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;
}
ptd[i + 1] = '\0';

在这里,
i
在循环中递增,这样最后一个
i
将已经超过构建的字符串。因此,
ptd[i+1]='\0'中的额外增量行将保留一个未初始化的字符。所以正确的代码应该是
ptd[i]='\0'

您没有正确终止字符串:

while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;
}
ptd[i + 1] = '\0';
int i = 0;
while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;               <=== increment, hence 'i' points to the char *after* the last one
}
ptd[i + 1] = '\0';     <== now you move *one char more* from the last one
strcat(ptd, ".txt"); // append .txt

在这里,
i
在循环中递增,这样最后一个
i
将已经超过构建的字符串。因此,
ptd[i+1]='\0'中的额外增量行将保留一个未初始化的字符。所以正确的代码应该是
ptd[i]='\0'

您没有正确终止字符串:

while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;
}
ptd[i + 1] = '\0';
int i = 0;
while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;               <=== increment, hence 'i' points to the char *after* the last one
}
ptd[i + 1] = '\0';     <== now you move *one char more* from the last one
strcat(ptd, ".txt"); // append .txt

在这里,
i
在循环中递增,这样最后一个
i
将已经超过构建的字符串。因此,
ptd[i+1]='\0'中的额外增量行将保留一个未初始化的字符。所以正确的代码应该是
ptd[i]='\0'

您没有正确终止字符串:

while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;
}
ptd[i + 1] = '\0';
int i = 0;
while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;               <=== increment, hence 'i' points to the char *after* the last one
}
ptd[i + 1] = '\0';     <== now you move *one char more* from the last one
strcat(ptd, ".txt"); // append .txt
在这里,
i
在循环中递增,这样最后一个
i
将已经超过构建的字符串。因此,
ptd[i+1]='\0'中的额外增量行将保留一个未初始化的字符。所以正确的代码应该是
ptd[i]='\0'

int i = 0;
while ((x = getchar()) != '\n'){
    ptd[i] = x;
    i++;               <=== increment, hence 'i' points to the char *after* the last one
}
ptd[i + 1] = '\0';     <== now you move *one char more* from the last one
strcat(ptd, ".txt"); // append .txt
这意味着(可能是)用GCC编译的程序以干净的堆开始,而MSVC以充满垃圾的堆开始

当MSVC用垃圾填充堆时,它可以做到这一点,这有助于检测像您这样的人为错误

请查看此页面:“使用调试堆查找缓冲区溢出”部分:

调试堆还使用已知值填充新内存块

目前,实际使用的字节值如下:

新对象(0xCD)

新对象在分配时将填充0xCD

那么,如果你看这里:

你会看到:

Í205 0xcd 0315Í后记(“)hungarumlaut

就是您在文件名中看到的字符

这意味着(可能是)用GCC编译的程序以干净的堆开始,而MSVC以充满垃圾的堆开始

当MSVC用垃圾填充堆时,它可以做到这一点,这有助于检测像您这样的人为错误

请查看此页面:“使用调试堆查找缓冲区溢出”部分:

调试堆还使用已知值填充新内存块

目前,实际使用的字节值如下:

新对象(0xCD)

新对象在分配时将填充0xCD

那么,如果你看这里:

你会看到:

Í205 0xcd 0315Í后记(“)hungarumlaut

就是您在文件名中看到的字符

这意味着(可能是)用GCC编译的程序以干净的堆开始,而MSVC以充满垃圾的堆开始

当MSVC用垃圾填充堆时,它可以做到这一点,这有助于检测像您这样的人为错误

请查看此页面:“使用调试堆查找缓冲区溢出”部分:

调试堆还使用已知值填充新内存块

目前,实际使用的字节值如下:

新对象(0xCD)

新对象在分配时将填充0xCD

那么,如果你看这里:

你会看到:

Í205 0xcd 0315Í后记(“)hungarumlaut

就是您在文件名中看到的字符

这意味着(可能是)用GCC编译的程序以干净的堆开始,而MSVC以充满垃圾的堆开始

当MSVC用垃圾填充堆时,它可以做到这一点,这有助于检测像您这样的人为错误

请查看此页面:“使用调试堆查找缓冲区溢出”部分:

调试堆还使用已知值填充新内存块

目前,实际使用的字节值如下:

新对象(0xCD)

新对象在分配时将填充0xCD

那么,如果你看这里:

你会看到:

Í205 0xcd 0315Í后记(“)hungarumlaut


就是您在文件名中看到的字符。

我肯定您在那里看到了一些垃圾。也许是偶然的,它等于零,所以你得到了正确的终止。还有一个问题,因为那个垃圾东西让我困惑