英文:
How to properly scanf things from txt file in c
问题
这是我的代码,我试图从一个结构化如下的文件中进行 fscanf:
Tom Veri 1234567890 HJA
Peter Schmit 9874561230 ABA
Jhon Smart 0192837465 DPA
Harry Tompson 0912354876 PHA
但是在编译后,我的输出很奇怪,为什么会这样发生:
以下是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int nOfLines(FILE* file);
struct inputAbc
{
char ime[20+1];
char prezime[20+1];
char jmbg[20+1];
char sign[3+1];
};
int main()
{
int nLines, i;
FILE* input = NULL;
FILE* output;
struct inputAbc model_arr[10];
input = fopen("input.txt", "r");
output = fopen("output.txt", "w");
nLines = nOfLines(input);
for(i = 0; i < nLines+1; i++)
{
fscanf(input, "%s %s %s %s",
model_arr[i].ime, model_arr[i].prezime,
model_arr[i].jmbg, model_arr[i].sign);
}
for(i = 0; i < nLines+1; i++)
{
fprintf(output,
"ime: %s\nprezime: %s\njmbg: %s\nznakovlje: %s\n\n",
model_arr[i].ime, model_arr[i].prezime,
model_arr[i].jmbg, model_arr[i].sign);
}
return 0;
}
int nOfLines(FILE *file)
{
int lines = 0;
int index;
while(!feof(file))
{
index = fgetc(file);
if(index == '\n')
lines++;
}
return lines;
}
请注意,我已经删除了代码部分,只提供了代码的翻译。
英文:
This is my code and what am I trying to do is to fscanf from file that is structured like this:
Tom Veri 1234567890 HJA
Peter Schmit 9874561230 ABA
Jhon Smart 0192837465 DPA
Harry Tompson 0912354876 PHA
And after compiling my output is weird why that happens:
Code is below
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int nOfLines(FILE* file);
struct inputAbc
{
char ime[20+1];
char prezime[20+1];
char jmbg[20+1];
char sign[3+1];
};
int main()
{
int nLines, i;
FILE* input = NULL;
FILE* output;
struct inputAbc model_arr[10];
input = fopen("input.txt", "r");
output = fopen("output.txt", "w");
nLines = nOfLines(input);
//printf("%d\n", nLines+1);
for(i = 0; i < nLines+1; i++)
{
fscanf(input ,"%s %s %s %s",
model_arr[i].ime, model_arr[i].prezime,
model_arr[i].jmbg, model_arr[i].sign);
}
for(i = 0; i < nLines+1; i++)
{
fprintf(output,
"ime: %s\nprezime: %s\njmbg: %s\nznakovlje: %s\n\n",
model_arr[i].ime, model_arr[i].prezime,
model_arr[i].jmbg, model_arr[i].sign);
}
return 0;
}
int nOfLines(FILE *file)
{
int lines = 0;
int index;
while(!feof(file))
{
index = fgetc(file);
if(index == '\n')
lines++;
}
return lines;
}
答案1
得分: 2
以下是您提供的代码的翻译:
以下是建议的代码:
1. 清晰地编译
2. 执行所需的功能
3. 生成所需的输出
4. 消除了一些“魔术”数字
5. 消除不必要的变量
6. 用注释来帮助 OP 理解代码
7. 在 `fscanf()` 中使用了 'max character' 修饰符,以避免缓冲区溢出和由此导致的未定义行为
8. 消除了 `#include <string.h>`,因为在发布的代码中未使用相关功能
9. 在退出之前正确地清理(关闭打开的文件)。
10. 适当检查 `fopen()` 和 `fscanf()` 的 I/O 错误
11. 对变量 `i` 和 `j` 使用了 `size_t`,因为它们永远不会小于0
现在,以下是建议的代码:
#include <stdio.h>
#include <stdlib.h>;
struct inputAbc
{
char ime[20 + 1];
char prezime[20 + 1];
char jmbg[20 + 1];
char sign[3 + 1];
};
#define MAX_LINES 10
int main(void)
{
FILE *input = NULL;
FILE *output = NULL;
struct inputAbc model_arr[MAX_LINES];
if ((input = fopen("input.txt", "r")) == NULL)
{
perror("fopen to read 'input.txt' failed");
exit(EXIT_FAILURE);
}
// implied else, fopen for input successful
if ((output = fopen("output.txt", "w")) == NULL)
{
perror("fopen to write 'output.txt' failed");
fclose(input);
exit(EXIT_FAILURE);
}
// implied else, fopen for output successful
size_t i; // file global scope since needed in next code block
for (i = 0; i < MAX_LINES; i++)
{
if (fscanf(input, "%20s %20s %20s %3s",
model_arr[i].ime,
model_arr[i].prezime,
model_arr[i].jmbg,
model_arr[i].sign) != 4)
{
break;
}
}
for (size_t j = 0; j < i; j++)
{
fprintf(output,
"ime: %s\nprezime: %s\njmbg: %s\nznakovlje: %s\n\n",
model_arr[j].ime,
model_arr[j].prezime,
model_arr[j].jmbg,
model_arr[j].sign);
}
fclose(input);
fclose(output);
return 0;
}
英文:
the following proposed code:
- cleanly compiles
- performs the desired functionality
- produces the desired output
- eliminates some of the 'magic' numbers
- eliminates unneeded variables
- is commented to assist OP in understanding the code
- uses 'max character' modifiers in the
fscanf()
to avoid any possibility of a buffer overflow and the resulting undefined behavior - eliminates:
#include <string.h>
because none of the associated functionality is used in the posted code - properly cleans up (by closing open files) before exiting.
- properly checks for I/O errors for
fopen()
andfscanf()
- used
size_t
for variablesi
andj
as they can never be less than 0
and now, the proposed code:
#include <stdio.h>
#include <stdlib.h>
struct inputAbc
{
char ime[20+1];
char prezime[20+1];
char jmbg[20+1];
char sign[3+1];
};
#define MAX_LINES 10
int main( void )
{
FILE* input = NULL;
FILE* output = NULL;
struct inputAbc model_arr[ MAX_LINES ];
if( (input = fopen("input.txt", "r")) == NULL )
{
perror( "fopen to read 'input.txt' failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen for input successful
if( (output = fopen("output.txt", "w") ) == NULL )
{
perror( "fopen to write 'output.txt' failed" );
fclose( input );
exit( EXIT_FAILURE );
}
// implied else, fopen for output successful
size_t i; // file global scope since needed in next code block
for( i = 0; i < MAX_LINES; i++ )
{
if( fscanf(input ,"%20s %20s %20s %3s",
model_arr[i].ime,
model_arr[i].prezime,
model_arr[i].jmbg,
model_arr[i].sign) != 4 )
{
break;
}
}
for( size_t j = 0; j < i; j++ )
{
fprintf(output,
"ime: %s\nprezime: %s\njmbg: %s\nznakovlje: %s\n\n",
model_arr[j].ime,
model_arr[j].prezime,
model_arr[j].jmbg,
model_arr[j].sign);
}
fclose( input );
fclose( output );
return 0;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论