c语言中的fopenfopen.错误的问题

博客访问: 846294
博文数量: 444
博客积分: 7854
博客等级: 少将
技术积分: 3265
注册时间:
1、使用fopen(文件打开)时,引号的区别。char filename[20] = "NULL";char directory[20] = "NULL";printf ("please input the file name.\n");scanf ("%s", filename);fp = fopen ("filename", "w"); 加上引号将以filename本身为名在当前目录下建立文件fp = fopen (filename, "w"); 不加引号将以数组filename的值为名在当前目录下建立文件如果要在某个目录下建立以数组filename的值为名的文件,可以如下这样: sprintf(directory,"/home/renewjoy/%s",filename); //sprintf可以连接两个字符串或者:strcpy(directory, "/home/renewjoy/"); //#include strcat(directory, filename);fp = fopen (directory, "w"); 2、fopen中,貌似不能解析"~"符号,但可以解析"."、".."路径。fp = fopen ("~/study/c/test.c", "w"); 这样会报错。fp = fopen ("$HOME/study/c/test.c", "w"); 同样会报错。fp = fopen (/home/renewjoy/study/c/test.c, "w"); 必须用绝对路径。fp = fopen ("../test.c", "w"); 可以在当前目录的父目录下建立文件test.c3、以写的方式打开文件:fopen ("./open_file", "w"),并不能读文件的内容,必须把打开方式设为读和写:"w+"
阅读(3205) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
请登录后评论。C语言-一个fopen函数中未使用二进制模式(b)引发的血案 - John_ABC - 博客园
随笔 - 416, 文章 - 0, 评论 - 17, 引用 - 0
转自:http://blog.csdn.net/hinyunsin/article/details/6401854
最近写了一个网络文件传输模块,为了让这个模块具有更好的移植性,我尽量使用C标准IO API来编写代码。模块是在Linux下面写的,一点问题都没有。但是昨天把客户端的代码移植到了windows上,结果就出现了一个很奇怪的问题,客户端从服务器端下载的数据保存在本地总是比服务器上的原始文件要大,下载的二进制文件(比如zip文件)总是被破坏,而下载的文本文件却看不出任何问题。看了半天代码,一直把注意力放在fread和fwrite函数上,怎么都看不出什么问题,Linux下测试也一点问题没有。于是我就又用fopen,fread,fwrite函数写了一个文件复制的小程序,代码如下:
#define BUF_SIZE
const char src[]="from";
const char dest[]="to";
int main(int argc,char **argv){
FILE *fp,*fp2;
char buf[BUF_SIZE];
fp=fopen(src,"r");
fp2=fopen(dest,"w");
num=fread(buf,sizeof(char),BUF_SIZE,fp);
while(num&0){
fwrite(buf,sizeof(char),num,fp2);
num=fread(buf,1,BUF_SIZE,fp);
fclose(fp);
fclose(fp2);
结果显示,复制的文件依然比原始文件要大。
于是在网上用关键字"fread fwrite 复制 文件 大小不一"去查了,发现有两个人也说大小不一,但是他们跟我不一样的是,他们的fwrite函数第3个参数不是这里的num,而是BUF_SIZE,这样 很显然得到的结果一般会比原始的大,因为最后一个数据包读取的大小很可能比BUF_SIZE要小。查了很久知道,突然看到一个人的代码上fopen函数是 采用二进制打开的:fopen("xxx","wb"),于是我尝试着改成二进制,一试,居然成功了!!!
于是就查阅MSDN,上面说:
Open in binary (untranslated) translations involving carriage-return and linefeed characters are suppressed.
If t or b is not given in mode, the default translation mode is defined by the global variable _fmode.
If t or b is prefixed to the argument, the function fails and returns NULL.
意识是:使用二进制模式打开,翻译换行符的时候会进行压缩。具体是什么意思还不太明白,于是又到网上特地搜了一下fopen中二进制和文本的区别。中说的很不错:
  在学习C语言文件操作后,我们都会知道打开文件的函数是fopen,也知道它的第二个参数是 标志字符串。其中,如果字符串中出现'b',则表明是以打开二进制(binary)文件,否则是打开文本文件。
  那么什么是文本文件,什么是二进制文件呢? 可能大多数人都没有仔细考虑过。
  在Windows和DOS系统中,狭义的文本文件是指扩展名为txt的文件。实际上,那些没有规定格式的,由可理解的的ASCII以及 其他编码文字组成的文件都是文本文件,如C源程序文件,HTML超文本,XML。除此之外的其他文件都是二进制文件,如Word文件DOC,图象格式文件 JPG。
  但是,所谓使用fopen标志打开文本文件与二进制文件的说法并不准确。正确的说法应该是--以文本方式和二进制方式打开文件。因为我们用两种方式都可以任意的文件。
  即使这样,为什么还要区分两种方式呢?
  这是因为这两种方式在读写文件时的操作是不一样的。
  二进制方式很简单,读文件时,会原封不动的读出文件的全部內容,写的時候,也是把內存缓冲区的內容原封不动的写到文件中。
  而文本方式就不一样了,在写文件时,会将换行符号CRLF(0x0D 0x0A)全部转换成单个的0x0A,并且当遇到结束符CTRLZ(0x1A)时,就认为文件已经结束。相应的,写文件时,会将所有的0x0A换成0x0D0x0A。
所以,若使用文本方式打开二进制文件时,就很容易出现文件读不完整,或內容不对的错误。即使是用文本方式打开文本文件,也要谨慎使用,比如复制文件,就不应该使用文本方式。
  要特別注意的是,上面这样的说法仅适用于DOS和Windows系统。在Unix和其他一些系统中,沒有文本方式和二进制方式的区分,使不使用'b'标志都是一样的。这是由于不同操作系统对文本文件换行符的定义,和C语言中换行符的定义有所不同而造成的。
  如上文已提到,DOS和Windows系统使用CRLF(0x0D 0x0A)双字节作为文本文件换行符,而Unix文本文件的换行符只有一个字节LF(0x0A)为。在C语言中,也是以LF即'/n'为换行符。
  由于DOS/Windows定义的换行符和C语言的不一致,C语言的标准输入输出函数适行读写文本文件时,就适行了CRLF-&LF的转换。而Unix的定义和C语言的是一样的,就不必转换了。
  那么,为什么會有定义不一致的情况呢,这纯属历史原因。当初C是在Unix上发展的,对换行的定义自然就一样了。其后C被引入到DOS 系统,为了使原有的C程序能不加修改的读写DOS的文本文件,所以就在文件读写上做了修改。随着DOS/Windows成为主流平台,这个当初为了兼容而 做的修改給众多的C语言开发者添了这样一个小小的麻烦。
从这篇文章中,看出,我从服务器上下载数据的并写入文件的时候,所有0x0A的数据通通被windows按照0x0Dx0A的方式写入了,结果数据自然就变大了!
我做了一个实验,在Linux下面输入了几千个回车符,这些回车符以0x0A的方式写入文件中,我使用上面的程序对它进行了复制,使用二进制方式打开,如下图:
很明显,所有的0x0A都被替换成了0x0D0x0A,文件大小翻倍了!
于是乎前面的每个问题都得到了解释,文件变大,文本文件看不出问题(反正编辑器自动给你换行了),二进制文件被破坏,Linux下没有问题(不区分文本和二进制),windows有!
我们把代码修改为二进制模式,于是整个世界回归了正常轨道!
#define BUF_SIZE
const char src[]="from";
const char dest[]="to";
int main(int argc,char **argv){
FILE *fp,*fp2;
char buf[BUF_SIZE];
fp=fopen(src,"rb");
fp2=fopen(dest,"wb");
num=fread(buf,sizeof(char),BUF_SIZE,fp);
while(num&0){
fwrite(buf,sizeof(char),num,fp2);
num=fread(buf,1,BUF_SIZE,fp);
fclose(fp);
fclose(fp2);在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
C语言使用fgetc读取文件出错。
#include&stdio.h&
#include&string.h&
#include&conio.h&
int main() {
int num[8];
int count = 0;
fp = fopen("2.txt","r");
while( (ch = fgetc(fp)) != 255){
for(int i=0;i&8;i++){
num[i] = ch&&(7-i)&1;
printf("%d",num[i]);
printf(" ");
if (++count == 8) {
printf("\n");
count = 0;
fclose(fp);
读取的文件在这里:www.ewinds.pw/2.txt
很奇怪,用自己写的程序读取文件,结果是这样的:
用ultreaEdit读取出来结果如下:
想要知道为什么读取到第二十一个字节,一直往后,全部变成了.求大家指点,不甚感激
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
fp = fopen("2.txt","rb");
#include &stdio.h&
#include &string.h&
#include &conio.h&
#include &stdlib.h&
int main(void)
FILE* fp = fopen("2.txt", "rb");
printf("File opening failed\n");
return EXIT_FAILURE;
int count = 0;
// note: int, not char, required to handle EOF
while ((c = fgetc(fp)) != EOF) { // standard C I/O file reading loop
for(int i=0;i&8;i++){
printf("%d", c&&(7-i)&1);
printf(" ");
if (!(++count%8)) {
printf("\n");
//getch();
if (ferror(fp))
printf("\nI/O error when reading\n");
else if (feof(fp))
printf("\nEnd of file reached successfully\n");
fclose(fp);
00 00 11010 00 01 01010 00 11 01110 00 01 01101 00 11 01001 00 01 11111 00 00 00110 00 10 11010 00 01 01011 00 01 01101 00 11 00111 00 00 11000 00 01 01101 00 01 10000 00 11 01001 00 00 00111 00 11 00010 00 10 01011 00 10 00111 00 11 01001 00 01 11111 00 00 00110 00 10 11010 00 11 11011 00 01 00000 00 00 01111 00 10 01101 00 10 10011 00 10 01110 00 01 00110 00 10 01110
End of file reached successfully
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
fgetc的返回值是int类型。一个可能的解释是fgetc失败了,返回了-1,导致你换算后的二进制全是1。把ch的声明改成int
while( (ch = fgetc(fp)) != 255){
while( (ch = fgetc(fp)) != -1){
while之后打印一下errno:
printf("%d %s\n", errno, strerror(errno));
看到底是什么原因导致fgetc失败.
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。21:34 提问
fopen打开绝对路径中文件出错的问题
在打开绝对路径中文件时,先用CStdioFile类的Open函数打开文件,再用FILE类用fopen函数打开文件就出错了(返回为空),不知为什么。是不是CStdioFile类打开文件的时候把路径什么改变了?
按赞数排序
查看error_no等错误信息,看是路径问题还是其它错误。还可以打印fopen的路径看是否正确。
打开中文路径用c标准库的函数吧, _wfopen
记得用unicode编码的字符串路径.
确认下是不是和中文有关,你的路径的拼接有没有问题,比如说一个是unicode的字符串,一个是gb的,连起来就不对了。用W L之类的宏看看。
使用_tfopen打开中文路径文件,引用tchar.h头文件
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐【图片】求助:fopen() 为什么报错呢【c语言吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:584,524贴子:
求助:fopen() 为什么报错呢收藏
如下图,当我加进去图中选择部分的“报错”语句是,就没法运行了;把它删掉就一切正常;这是为什么呢?错误提示是这样的:
让你用fopen_s替代fopen呗
代替 fopen 之后,提示错误:
把char buf[64]和size_t ret放到main函数开头。
把fp!=0的0前面加个 /
如何解决“This function or variable may be unsafe”更多的关于“Visual Studio”的问题可以看:
恐惧就是这样一个懦夫,当你触及他的底线,接受事情最坏的结果,然后开始准备和它大干一场的时候,它早就不知道躲到哪里去了。
fopen 失败才会返回 NULL 检测反了 ...没记错 C89 不允许随意声明变量 .. 一般都放在首部 ... 你改成.cpp 则没事 ...
c语言,博为峰IT培训免费试听,0元入学,现在更有多重优惠,仅限今天!博为峰,真正的为年轻人服务的企业,14年间培训15万余名it工程师,成绩斐然!
去掉那段代码,运行无误!
char buf[64] = {0}; 这行代码提到FILE *fp之前。C89标准禁止在可执行语句之后定义变量。
#include&stdio.h&#include&conio.h&#include&stdlib.h&int main(void){
char buf[64]={0};
FILE*fp=fopen(&D:/aa.txt&,&r&);
perror(&fopen&);
ret=fread(buf,1,63,fp);
printf(&%s size = %ld\n\n&,buf,ret);
fclose(fp);
return 0;}
修改后的代码:#include&stdio.h&#include&stdlib.h&int main(void){char buf[64] = { 0 };size_FILE*fp = fopen(&D:/aa.txt&, &r&);if (!fp){perror(&fopen&);exit(-1);}ret = fread(buf, 1, 63, fp);printf(&%s size = %ld\n\n&, buf, ret);fclose(fp);getchar();return 0;}aa.txt 上的内容:#include&stdio.h&#include&conio.h&#include&stdlib.h&int main(void){char buf[64]={0};size_FILE*fp=fopen(&D:/aa.txt&,&r&);if (!fp){perror(&fopen&);exit(-1); }ret=fread(buf,1,63,fp);printf(&%s size = %ld\n\n&,buf,ret);fclose(fp);getch();return 0;}最后运行的效果:
size_t是什么?
命中有很多事情足以把你打倒,但真正能把你打倒的是你的心态。
登录百度帐号}

我要回帖

更多关于 c语言中fopen的用法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信