I am trying to create a function that appends !!
at the very end of each line from(inclusive)-to(exclusive) of a text file. After I had several complications I actually succeeded. But not entirely.
我正在尝试创建一个附加的功能!在每行的最后,从(包括) - 到(独占)文本文件。在我有几个并发症后,我实际上成功了。但并非完全如此。
int incldue_auto (char *script, unsigned int offsetLine, unsigned int endLine)
{
size_t fileSize;
size_t content = (endLine - offsetLine) * 3; // New characters
char *buffer;
FILE* fp;
if((fp = fopen(script, "r")) == NULL) //return(1);
if(fseek(fp, 0l, SEEK_END) != 0) //return(2);
if((fileSize = ftell(fp)) == (-1l)) //return(3);
if(fseek(fp, 0l, SEEK_SET) != 0) //return(2);
if((buffer = calloc(fileSize + content, sizeof(char))) == NULL) //return(4);
if(fread(buffer, sizeof(char), fileSize, fp) != fileSize) //return(5);
if(fclose(fp) == EOF) //return(6);
{
int i, i2;
int lines = 0, ln = 0;
for(i = 0; i < fileSize; i++)
{
if(ln >= (endLine - offsetLine) || i[buffer] == '\0') break;
if(i[buffer] == '\n')
{
lines++;
if(lines >= offsetLine && lines < endLine)
{
char* p = (buffer + i); // \n
//if(*(p - 1) == '\n') continue;
memmove(p + 3,
p,
strlen(p)); // <-- Problematic line (I think)
memcpy(p, " !!", 3);
i += 3;
ln++;
}
}
}
fp = fopen(script, "w");
fwrite(buffer, fileSize + content, sizeof(char), fp);
fclose(fp);
}
free(buffer);
return 0;
}
It relatively works just fine, except for that it doesn't append to the last line. And it fills the text file with spaces (NULLs maybe) at the end. I think it is because I am also moving the enzero-ed additional area content
with that:
它相对工作得很好,除了它不附加到最后一行。并且它最后用空格填充文本文件(可能为NULL)。我认为这是因为我也在使用以下内容移动enzero-ed附加区域内容:
memmove(p + 3,
p,
strlen(p)); // <-- Problematic line (I think)
So maybe I need to figure out what is the appropriate formula I have to use in order to make this work. Any ideas of how to make this work ?
所以,也许我需要弄清楚我必须使用什么样的公式才能使这项工作成功。有关如何使这项工作的任何想法?
2 个解决方案
#1
2
Your loop condition is wrong:
您的循环条件错误:
for(i = 0; i < fileSize; i++)
After you have appended content to some lines, the end of the last line is moved beyond filesize
and thus will no longer be treated.
将内容附加到某些行后,最后一行的末尾将移出文件大小,因此将不再处理。
You test whether the end of the buffer has been reached with i[buffer] == '\0'
, but that may lead to reading beyond the buffer after having done all shifts and there are nio more trailing zeroes. This shouldn't happen, because the end line condition is checked first, but better be safe by calloc
ing one more char, which will then make buffer
a zero-terminated string.
您可以使用i [buffer] =='\ 0'测试是否已达到缓冲区的结尾,但是在完成所有移位后,可能会导致读取超出缓冲区,并且有更多的尾随零。这不应该发生,因为首先检查结束行条件,但最好通过再调用一个char来安全,这将使缓冲区成为以零结尾的字符串。
When you shift fewer lines than requested, because the file doesn't have the requested lines – say you shift lines 20 to 40 in a 30-line file – you still print out the trailing zeroes. You could either print the zero-terminated buffer as a string or you should keep track of the actual amount of data being appended.
当您移动的线数少于请求的数量时,因为文件没有请求的行 - 比如说你在30行文件中移动20到40行 - 你仍然会打印出尾随的零。您可以将零终止缓冲区打印为字符串,也可以跟踪要追加的实际数据量。
You keep two redundant line counts, lines
and ln
. Pick one and remove the other; it only needlessly confuses the code.
你保留两个冗余行数,行和ln。选择一个并删除另一个;它只会不必要地混淆代码。
#2
0
Maybe you can put one more condition in your loop:
也许你可以在循环中再添加一个条件:
if(lines >= offsetLine && lines < endLine)
{
...//your code here before 'memcpy(p, " !!", 3);'
if(lines==endline)
{
memmove(p + 3, p, strlen(p));
}
//the end of your code here:
memcpy(p, " !!", 3);//your code here
i += 3;
ln++;
}
Then you will move 3 more characters if this is the last line and put '!!' just after this.
然后,如果这是最后一行,你将移动另外3个字符并放入'!!'就在这之后。
#1
2
Your loop condition is wrong:
您的循环条件错误:
for(i = 0; i < fileSize; i++)
After you have appended content to some lines, the end of the last line is moved beyond filesize
and thus will no longer be treated.
将内容附加到某些行后,最后一行的末尾将移出文件大小,因此将不再处理。
You test whether the end of the buffer has been reached with i[buffer] == '\0'
, but that may lead to reading beyond the buffer after having done all shifts and there are nio more trailing zeroes. This shouldn't happen, because the end line condition is checked first, but better be safe by calloc
ing one more char, which will then make buffer
a zero-terminated string.
您可以使用i [buffer] =='\ 0'测试是否已达到缓冲区的结尾,但是在完成所有移位后,可能会导致读取超出缓冲区,并且有更多的尾随零。这不应该发生,因为首先检查结束行条件,但最好通过再调用一个char来安全,这将使缓冲区成为以零结尾的字符串。
When you shift fewer lines than requested, because the file doesn't have the requested lines – say you shift lines 20 to 40 in a 30-line file – you still print out the trailing zeroes. You could either print the zero-terminated buffer as a string or you should keep track of the actual amount of data being appended.
当您移动的线数少于请求的数量时,因为文件没有请求的行 - 比如说你在30行文件中移动20到40行 - 你仍然会打印出尾随的零。您可以将零终止缓冲区打印为字符串,也可以跟踪要追加的实际数据量。
You keep two redundant line counts, lines
and ln
. Pick one and remove the other; it only needlessly confuses the code.
你保留两个冗余行数,行和ln。选择一个并删除另一个;它只会不必要地混淆代码。
#2
0
Maybe you can put one more condition in your loop:
也许你可以在循环中再添加一个条件:
if(lines >= offsetLine && lines < endLine)
{
...//your code here before 'memcpy(p, " !!", 3);'
if(lines==endline)
{
memmove(p + 3, p, strlen(p));
}
//the end of your code here:
memcpy(p, " !!", 3);//your code here
i += 3;
ln++;
}
Then you will move 3 more characters if this is the last line and put '!!' just after this.
然后,如果这是最后一行,你将移动另外3个字符并放入'!!'就在这之后。