英文:
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_tfor variablesiandjas 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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论