用行和列尝试文件I / O,放置FILE时遇到问题* [英] Attempting File I/O with lines and columns, problems with positioning the FILE *
问题描述
我正在尝试编写2个函数:
I am attempting to write 2 functions :
- 一个将FILE *移动到传递索引的函数
- 另一种将FILE *中的内容从2个索引之间复制到字符串中。
发生了非常莫名的错误,我一直在尝试对其进行修复
Very inexplicable errors are occurring, and I have been trying to fix it for quite a few hours now, and am about to collapse, please point out my folly.
观察到的行为:
-
chknbuff()
跳过了最后一个字符,因此我贴上了一些可以解决该问题的代码。 - 在第一行之外阅读( ln = 2,例如col = x)在其他文件的
chkncpy()
中触发EOF错误。 - 禁止
chknmove()
的EOF警告给出Segmentation Fault
s,这意味着EOF
确实遇到了。
chknbuff()
is skipping the last char, so I taped on some code that would fix that.- Reading beyond the 1st line (ln=2, col=x for eg.) triggers the EOF error in
chkncpy()
in other files . - Suppressing
chknmove()
's EOF warning givesSegmentation Fault
s , which means anEOF
is really being encountered.
代码:
#include <stdio.h>
/*-------Function-Definitions------------*/
int chknmove(FILE *tomove,long long line,long long col){
// moves FILE * to line & col passed
rewind(tomove); int chk,f; long long i,q; i=0; q=0; f=0;
if(line>=1 && col>=1){
while(i < line){
chk = fgetc(tomove);
if(chk == EOF){
printf("\n Invalid Index.\n");f=-1;break;
}
else if(chk == '\n'){
if(i == line - 1){
printf("\n Invalid Index.\n");f=-1;break;
}
i++; q = 0;
}
else if(i == line - 1 && q == col - 1){
break;
}
else
q++;
}
if(f==0)
fseek(tomove,-1,SEEK_CUR);
}
else{
printf("\n Invalid Index.\n");f=-1;
}
return f;
}
int chknbuff(FILE *source, char *dest, long long beginln, long long begincol, long long endln, long long endcol){
// copies file contents from beginning line&cols to end lines&cols to a string.
int z = chknmove(source,beginln,begincol);
if(z==0){
int chk; long long i,q,m; i=0; q=0; m=0; //endcol++;
if(endln>=1 && endcol>=1 && endln>=beginln){
while(i < endln){
chk = fgetc(source);
if(chk == EOF){
printf("\n Invalid Index1.\n");z=-1;break;
}
else if(chk == '\n'){
if(i == endln-1){
printf("\n Invalid Index2.\n");z=-1;break;
}
dest[m]=chk;m++; i++; q = 0;
}
else if(i == endln-1 && q == endcol-1 ){
break;
}
else{
dest[m]=chk;m++; q++;
}
}
if(z==0){
fseek(source,-1,SEEK_CUR);
chk = fgetc(source);
if(chk!=EOF)
dest[m]=chk; m++;
}
dest[m++]='\0';
}
else{
printf("\n Invalid Index3.\n");z=-1;
}
}
return z;
}
/*---------------------------------------------*/
int main(){
FILE * write = fopen("xyz","w");
if(write == NULL)
perror("\n Error ");
else{
printf("\n Filename : "); char fpart[501]; scarf("%500[^\n]",fpart); FILE * part = fopen(fpart,"r");
if(part==NULL)
perror("\n Error ");
else{
long long beginln, begincol, endln, endcol; char sep1,sep2;
printf("\n Starting Index : "); scanf("%lld%c%lld",&beginln,&sep1,&begincol); eat();
printf("\n Terminating Index : "); scanf("%lld%c%lld",&endln,&sep2,&endcol); eat();
char buff[MAX_F_BUFF];int f = chknbuff(part,buff,beginln,begincol,endln,endcol);
if(f==0)
fputs(buff,write);
}
int d = fclose(write);
if(d==EOF)
perror("\n Failed ");
else
printf("\n Success.\n");
}
return 0;
}
如果需要任何其他信息,请发表评论,我会尝试添加它
推荐答案
以下内容扩展了我的评论 您可以使用一个功能,并且只需一次遍历文件即可完成。范围中的字符用 putchar(chk);
打印,可以用 fputc(chk,write);
或 dest [count] = chk;
而是保存到文件或字符串缓冲区。
The following expands on my comment "you could do it all with one function", and does it with a single pass through the file. The characters in range are printed with putchar(chk);
, which could be replaced with fputc(chk, write);
or dest[count] = chk;
to save to a file or a string buffer, instead.
#include <stdio.h>
#include <stdlib.h>
// return number of characters in 'copy' range between (beginline, begincol) and (endline, endcol)
// line/col are 1-based and the 'copy' range is inclusive of both begin/end positions
long long copy_range(FILE* fyl, long long beginln, long long begincol, long long endln, long long endcol) {
long long line, col, count; int chk;
if (beginln < 1 || begincol < 1 || endln < beginln || (endln == beginln && endcol < begincol))
return -1;
// assume current file position is at the beginning, maybe 'rewind' if that's not guaranteed
line = 1; col = 1; count = -1;
// read the file sequentially
// start saving characters once (beginline, begincol) is reached
// break out of the loop after (endline, endcol) is reached
do {
// attempt to read character at position (line, col)
chk = fgetc(fyl);
// attempt failed, return error
// check count to see whether it happened before or within the 'copy' range
// check line to see if the entire line is past EOF vs. just the target column
if (chk == EOF) {
printf("\nInvalid %s %s.\n",
(count < 0) ? "Beginning" : "Ending",
(line == beginln) ? "Column" : "Line");
break;
}
// found newline character
if (chk == '\n') {
// error if looking for (beginln, begincol) and newline found on beginln before begincol
// or if looking for (endln, endcol) and newline found on endln before endcol
if (line == ((count < 0) ? beginln : endln)) {
printf("\nInvalid %s Column.\n",
(count < 0) ? "Beginning" : "Ending");
break;
}
// comment the following if *not* preserving newlines in 'copy' range
if (count >= 0) {
putchar(chk); count++;
}
// update position and move on
line++; col = 1; continue;
}
if (line == beginln && col == begincol) {
// enter the 'copy' range, start counting
printf("--- begin ---\n"); count = 0;
}
if (count >= 0) {
// save character if within the 'copy' range
putchar(chk); count++;
}
if (line == endln && col == endcol) {
// leave the 'copy' range, return the count
// if saving to a string, add the nul-terminator here, but do not increment counter
printf("\n---- end ----\n"); break;
}
col++;
} while (line <= endln);
return count;
}
int main() {
char fpart[501];
printf("\nEnter Filename:\n");
if (scanf("%500[^\n]", fpart) != 1) return -1;;
FILE* part = fopen(fpart, "r");
if (part == NULL) return errno;
long long beginln, begincol, endln, endcol;
printf("\nEnter Starting Index:\n");
if (scanf("%lld %lld", &beginln, &begincol) != 2) return -2;;
printf("\nEnter Terminating Index:\n");
if (scanf("%lld %lld", &endln, &endcol) != 2) return -3;
return copy_range(part, beginln, begincol, endln, endcol) > 0;
}
[ EDIT ]) ,其含义是将换行符计数为该行之前的最后一个位置,这是对上述内容的修改,在处理完字符后将'\n'
检查移到了该位置,并删除现在多余的换行符。
[ EDIT ] Following the comments, clarified to mean counting newlines as the last position on the line before, this is a modification of the above which moves the '\n'
check after the character is processed, and removes the now redundant newline echo.
long long copy_range(FILE* fyl, long long beginln, long long begincol, long long endln, long long endcol) {
long long line, col, count; int chk;
if (beginln < 1 || begincol < 1 || endln < beginln || endcol < ((endln == beginln) ? begincol : 1))
return -1;
line = 1; col = 1; count = -1;
do {
chk = fgetc(fyl);
if (chk == EOF) {
printf("\nInvalid %s %s.\n",
(count < 0) ? "Beginning" : "Ending",
(line == beginln) ? "Column" : "Line");
break;
}
if (line == beginln && col == begincol) {
printf("--- begin ---\n"); count = 0;
}
if (count >= 0) {
putchar(chk); count++;
}
if (line == endln && col == endcol) {
printf("\n---- end ----\n"); break;
}
if (chk == '\n') {
if (line == ((count < 0) ? beginln : endln)) {
printf("\nInvalid %s Column.\n",
(count < 0) ? "Beginning" : "Ending");
break;
}
line++; col = 1;
}
else
col++;
} while (line <= endln);
return count;
}
这篇关于用行和列尝试文件I / O,放置FILE时遇到问题*的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!