C 试图';插入';或';添加';变成一个文本文件-一个小问题
代码M.R.E已提供 症状“简单”:C 试图';插入';或';添加';变成一个文本文件-一个小问题,c,file,file-io,file-pointer,C,File,File Io,File Pointer,代码M.R.E已提供 症状“简单”: 在hello\nhello\nhelleof&插入'\'-ln=2&col=1(或者更确切地说是任何line>1&&col==1)时,程序奇怪地做得很好,但会吃掉'\n',导致第2行与第1行融合在一起,而不是你好\n\u你好\n你好 尝试在文件最后一行的a字符上插入“”@ln=3&col=5(或者更确切地说,在由EOF终止的行中的任何字符上插入“col>1)结果它跳过了行的最后一个实际字符:hello\nhello\nhellu EOF,而不是hello\n
hello\nhello\nhelleof
&插入'\
'-ln=2
&col=1
(或者更确切地说是任何line>1&&col==1
)时,程序奇怪地做得很好,但会吃掉'\n'
,导致第2行与第1行融合在一起,而不是你好\n\u你好\n你好
”@ln=3
&col=5
(或者更确切地说,在由EOF终止的行中的任何字符上插入“col>1
)结果它跳过了行的最后一个实际字符:hello\nhello\nhellu EOF
,而不是hello\nhello\nhellu EOF
col==1
,在由EOF终止的行中)将导致抛出错误消息(\n无效索引。
)'\n'
,EOF
)&它是如何计算的,以及通常的循环计数器时有一个缺陷,但我不明白
想法/算法:
- 从用户获取源文件
- 从用户处获取索引(行、列)
- 从源文件复制到tmp文件,直到(用户索引-1列)
- 现在,允许用户将字符串写入tmp文件的缓冲区
- 一旦用户终止输入,从用户索引复制到tmp,直到
EOF
- 重命名/删除+将tmp重命名为用户的源文件名
#包括
#包括
/*chknmove()、chkncpy()和/或main()中可能存在的错误区域;
还提供了使用的所有其他功能*/
长lncnt(文件*lcount){
/*使用fgets()统计文件中的行数*/
倒带(lcount);/*确保从开始计算行数*/
长行=0;字符行[501];
while((fgets(第501行,lcount))!=NULL){
行++;
}
倒带(lcount);/*将fptr保留为@0,0,而不是EOF*/
回流线;
}
int chknmove(文件*tomove,长行,长列){
/*用于检查并将文件*移动到特定行/列的函数*/
倒带(tomove);/*确保fptr位于文件的开头*/
int f=0;/*将check变量设置为0表示成功*/
如果(行您的代码太复杂:
- 复制文件开头的不同情况应合并到单个函数调用中,该函数调用将数据复制到第
行上的列col
处的字节(不包括该字节)
- 然后从用户输入进行复制
- 最后复制输入文件的其余部分
- 代码假定行和列从
1
开始编号。这可能是显而易见的,但您应该指定这一点,因为这可能不是每个人都能看到的
- 这种风格很难理解:你应该在二进制运算符周围使用水平空格,在关键字,
,
和;
之后和{
之前。在一行上塞满多个语句也不是一个好主意
以下是一个简化版本。通常,大多数代码都用于错误处理:
#包括
#包括
void flush_行(FILE*fp){/*读取当前行的其余部分*/
INTC;
而((c=getc(fp))!='\n'&&c!=EOF)
继续;
}
int copy_文件(文件*从,文件*到){
INTC;
而((c=getc(from))!=EOF){
if(putc(c,to)=EOF)
返回EOF;
}
返回0;
}
int copy_行(文件*from、int line1、int col1、文件*to){
int c,line=1,col=1;
对于(;;){
如果(行>=line1 | |(行==line1&&col>=col1))
打破
如果((c=getc(from))==EOF)
打破
if(putc(c,to)=EOF)
返回EOF;
col++;
如果(c=='\n'){
line++;
col=1;
}
}
返回0;
}
int writer(文件*写入){
[501];/*str中逐行存储输入的字符*/
char*p;
printf(“\n用\“/end/\”终止输入\n\n在下面键入:\n\n”);
而(fgets(in、501、stdin)){
如果((p=strstrstr(in,“/end/”)!=NULL){
/*若行中有“/end/”,则在/end/之前的所有字符都将写入文件,并且输入循环中断*/
int o=p-in;
if(fprintf(写入,'%s',o,in)<0)
返回EOF;
打破
}否则{
/*将行写入文件*/
如果(fputs(输入,写入)<0)
返回EOF;
}
}
返回0;
}
int main(){
/*要在给定索引下添加/插入文件的main*/
const char*temp_filename=“temp.Ctt”;
char fadd[501];/*文件名str*/
printf(“\n文件名:”);
如果(scanf(“%500[^\n]”,fadd)!=1)
返回1;
冲洗管线(标准DIN);
文件*add=fopen(fadd,“r”);
if(add==NULL){
perror(“\n无法打开输入文件”);
返回1;
}
int行,col;
/*阅读索引:基于1的行号和列号*/
printf(“\n索引:”);
如果(扫描频率(“%d%*c%d”、&行和列)!=2){
fprintf(stderr,“无效输入”);
返回1;
}
冲洗管线(标准DIN);
文件*tmp=fopen(临时文件名,“w”);
if(tmp==NULL){
perror(“\n无法创建临时文件”);
fclose(add);
返回1;
}
if(复制_行(添加、行、列、tmp)){
perror(“\n复制文件开头时出错”);
fclose(add);
fclose(tmp);
删除(临时文件名);
返回1;
}
if(编写器(tmp)){
perror(“\n写入用户输入时出错”);
fclose(add);
fclose(tmp);
删除(临时文件名);
返回1;
}
if(复制_文件(添加,tmp)){
perror(“\n复制剩余文件内容时出错”);