scanf功能无法正常扫描

时间:2014-05-02 07:52:29

标签: c string

这是代码:

StudentTree* readStudentFile(FILE* studentFile){
StudentTree *node=NULL;
StudentTree *tree=NULL;
int id;
char name[10]="\0";
char lastname[10]="\0";
int number;
int grade;

fscanf(studentFile,"%9d%10c%10c%4d%*c%3d",&id,name,lastname,&number,&grade);

以某种方式变量名称获取所有20个字符和变量lastname 只得到第二个10个字符。 我希望变量名只能获得前10个字符。

3 个答案:

答案 0 :(得分:2)

字符数组必须定义为

char name[11] = "\0";
char lastname[11] = "\0";

有足够的空间容纳10个字符加上终止的NUL字符。

您的情况可能会发生lastname紧随其后name 在内存中,以便打印name打印两个数组的字符 (也许更多,直到找到NUL字符。)

答案 1 :(得分:0)

解释相当简单。

首先:变量“name”和“lastname”可能由编译器在相邻位置分配。

第二:scanf的%c指令在“移动”char缓冲区中的字符时不会放置空终止符。

换句话说,“string”“name”将字符串lastname的null终止符作为第一个null终止符。

尝试使用%s指令,它将null终止符与%c命令区别开来。应该这样做。

干杯 莫里吉奥

答案 2 :(得分:0)

请注意

  1. 在格式字符串%9d中使用转化说明符scanf是错误的。这并不意味着fscanf将读取最多9位的整数。最大字段宽度只能与%s一起使用,或与%[..]开头的转换说明符一起使用。

  2. 您可以使用%s转换说明符,fscanf会自动在结尾处放置一个终止空字节,以标记字符串的结尾。

  3. 如果%*c的目的是跳过空白字符,那么你在这里不需要它,因为%d无论如何都会跳过所有前导空白字符。

  4. 您应该检查fscanf的返回值,以了解输入匹配和分配是否失败。 fscanf返回成功匹配和分配的输入项目数。

  5. 我建议如下 -

    // +1 for the terminating null byte
    // added by fscanf. This assumes that
    // name and lastname are no longer than
    // 10 characters in length.
    char name[10+1], lastname[10+1];
    int id;
    int number;
    int grade;
    
    // %10s means that fscanf will read at most 10 chars
    // or till it encounters a whitespace - whichever occurrs
    // first and then add a null byte at the end
    int retval = fscanf(studentFile, "%d%10s%10s%d%d", 
                        &id, name, lastname, &number, &grade);
    
    if(retval != 5) {
        // assignment failure due to 
        // bad format in the input
    }
    

    但是,最好使用fgets从文件中读取行,然后使用sscanf来解析行,因为如果fgets无法匹配并分配输入项,那么文件指针将留在未知位置。