有关在没有\0的情况下文件名长度的问题

sunyuqian 2010-01-03 11:41:11
大家好,这道题本身没有问题主要是对文件名长度有疑问,用/**/标出,请高手解答
这道题意思是将原文件名的前5个字符复制给新文件,当新文件名,然后把原文件每3个中的一个字符复制给新文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 10

int main(void)
{
FILE *in, *out;
int ch;
char source[LEN];
char cpy[LEN];
int count = 0;

printf("请输入文件名:\n");
scanf("%s",source);
if ((in = fopen(source, "r")) == NULL)
{
fprintf(stderr, "I couldn't open the file \"%s\"\n",
source);
exit(2);
}
strncpy(cpy,source, LEN - 5);
//cpy[LEN - 5] = '\0';
/*就是这个注释,正确的时候应该不注释它。当我注释后运行时,最多只能输入4个字符的文件名,可以创建成功,再多
就会说fprintf里的"Can't create output file."。我想道字符串没有添加\0为知什么还能在不多于4个字符的文件名的
时候创建文件,多于4个就出错了,这是为什么呢?如果没有添加\0,他应该多少字符都出错,为什么只是在4个字符以上才
出错?*/
strcat(cpy,".txt");
if ((out = fopen(cpy, "w")) == NULL)
{
fprintf(stderr,"Can't create output file.\n");
exit(3);
}
while ((ch = getc(in)) != EOF)
if (count++ % 3 == 0)
putc(ch, out);
if (fclose(in) != 0 || fclose(out) != 0)
fprintf(stderr,"Error in closing files\n");
return 0;
}
...全文
133 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xianyuxiaoqiang 2010-01-04
  • 打赏
  • 举报
回复
strncpy(cpy,source, LEN - 5);
strncpy在实现的时候,估计是先将cpy前面LEN - 5个字节清零。因此如果小于5,第5个字节就是'\0',否则就没有'\0'。
jernymy 2010-01-04
  • 打赏
  • 举报
回复
搂主可以在定义的时候就给初始化

char source[LEN] = {0};
char cpy[LEN] = {0};


或者定义的时候没有初始化,但之后用memset也是可以的

char source[LEN];
char cpy[LEN];

memset(source, 0, sizeof(source));
memset(cpy, 0, sizeof(cpy));
kingstarer 2010-01-04
  • 打赏
  • 举报
回复
你查一下snprintf就会知道了

snprintf有时会加上\0结尾 有时不会
macrojj 2010-01-04
  • 打赏
  • 举报
回复
strncpy(cpy,source, LEN - 5);
cpy[LEN - 5] = '\0';
很明显 是为了给cpy 一个结束的标记。我认为 并不是前5个字符 还是同名的txt。

赋值的时候 没有'\0' 所以要加一个字符串结束符
wzlhahr 2010-01-04
  • 打赏
  • 举报
回复
局部变量使用前进行初始化是必须的
wzlhahr 2010-01-04
  • 打赏
  • 举报
回复
如果加上memset(cpy, 0, sizeof(cpy));也是可以防止这种事情的
wzlhahr 2010-01-04
  • 打赏
  • 举报
回复
不多于4个时,使用strncpy时source中含有字符串结束标记,此标记也被拷贝到了cpy中
多余4个时,source中的字符串结束标记就无法拷贝到cpy中了,之后执行strcat时cpy在哪里结束就不确定了,有可能会发生数组越界
喝牛奶的熊 2010-01-04
  • 打赏
  • 举报
回复
你自己都明白了,就不用说啦。
就是你说的那个情况,没错!!
gelu1040 2010-01-04
  • 打赏
  • 举报
回复
按照你的定义 strncpy(cpy,source, LEN - 5);等价于strncpy(cpy,source, 5);

当strlen(source)>=5的时候,没地方放0了吧。也就是当strlen(source)>=5的时候,
strlen(cpy)=?,于是,后面的strcat(cpy,".txt")到底接在哪里?未知数啊。

出现这种情况,你的文件名其实是未知的文件名,当你的未知文件名非法的时候,创建自然不成功。
改成
sprintf(cpy,"%s.txt",source);
另外,LEN定义长点,一个短文件名都放不下的缓冲有什么呢?

sunyuqian 2010-01-04
  • 打赏
  • 举报
回复
谢谢了
东大坡居士 2010-01-04
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jernymy 的回复:]
搂主可以在定义的时候就给初始化
C/C++ codechar source[LEN]= {0};char cpy[LEN]= {0};

或者定义的时候没有初始化,但之后用memset也是可以的
C/C++ codechar source[LEN];char cpy[LEN];

memset(source,0,sizeof(source));
memset(cpy,0,sizeof(cpy));
[/Quote]


顶这个~~
sunyuqian 2010-01-03
  • 打赏
  • 举报
回复
好像有点明白了,在不多于4个的时候原文件名自动添加一个\0,所以复制后有\0,多于4就没有了,是这个原因吗?

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧