Printf两次输出相同的数组

时间:2016-05-20 05:48:58

标签: c file-io

我的主要问题是,当我从struct Item s打印时,s.name被打印两次。

代码:

#include <stdio.h>

struct Item{
    char code[5];
    char name[40];
};

int main(){
    FILE *f;
    struct Item s;

    //Open file
    f = fopen("ex.txt", "r");

    //Read from file
    fscanf(f, "%5c;%[a-zA-Z ]\n", s.code, s.name);

    //Print from file
    printf("%s %s", s.code, s.name); //Main problem here
    fclose(f);
}

输入(ex.txt):

AB011;Hello World

输出应为:

AB011 Hello World

但是它是:

AB011Hello World Hello World

这里发生了什么?

附加说明:我需要使用fscanf这个,以便我可以了解它是如何工作的。

2 个答案:

答案 0 :(得分:3)

fscanf的通话中,您正在使用

"%5c;%[a-zA-Z ]\n"

作为格式说明符。格式说明符的%5c部分将5个字符读取到s.code。这不会为终止空字符留出空间。

将{作为printf%s说明符的参数用于导致未定义的行为。 %s需要一个以空字符结尾的字符串。

您应该将code的大小更改为使用6个字符,然后在fscanf行之后使用空字符终止它。

#include <stdio.h>

struct Item{

    /// CHANGED HERE 
    char code[6];
    char name[40];
};

int main(){
    FILE *f;
    struct Item s;

    //Open file
    f = fopen("ex.txt", "r");

    //Read from file
    fscanf(f, "%5c;%[a-zA-Z ]\n", s.code, s.name);

    /// CHANGED HERE 
    s.code[5] = '\0';

    //Print from file
    printf("%s %s", s.code, s.name);
    fclose(f);
}

答案 1 :(得分:2)

  1. 如果您在code中存储5个字符,则大小必须为6个字节,包括\0终结符。

  2. 对于scanf %[5]c - 只读取5个字符,但不会添加终止\0

  3.   

    如果指定的宽度不是1,则该函数会准确读取宽度字符,并将它们存储在作为参数传递的数组的连续位置中。最后不附加空字符。

    您需要做的是在最后添加\0

    //Read from file
    fscanf(f, "%5c;%[a-zA-Z ]\n", s.code, s.name);
    s.code[5] = '\0';