malloc + fgets动态分配

时间:2012-06-26 19:51:14

标签: c malloc fgets

这是我的代码:

int main(int argc, char *argv[]){
    FILE *fp;
    char *tmp, *tmp2, *user, *pass, *line;
    printf("Inserire utente: "); scanf("%ms", &user); /* scanf %ms alloca dinamicamente la memoria */
    printf("Inserire password: "); scanf("%ms", &pass);
    line = malloc((strlen(user)+strlen(pass)) * sizeof(char)); /* DUBBIOOOOOOOOOO */
    fp = fopen("/home/pol/auth.txt", "r");
    if(fp == NULL){
        printf("Errore apertura file\n");
        return EXIT_FAILURE;
    }
    while(!feof(fp)){
        fgets(line, /* E QUI?? */ , fp);
        tmp = strtok(line, " ");
        tmp2 = strtok(NULL, "\n"); /* con fgets ultimo carattere è \n (se pwd=12 => 12\n) quindi devo tagliare prima di \n */
        if((strcmp(tmp,user) == 0) && (strcmp(tmp2,pass) == 0)){
            printf("USER: %s - PASS: %s\n", tmp, tmp2);
            free(user);
            free(pass);
            return EXIT_SUCCESS;
        }
        else{
            printf("Utente o password errati o non presenti nel DB\n");
            free(user);
            free(pass);
            return EXIT_FAILURE;
        }
    }
    return EXIT_SUCCESS;
}

我想知道是否:

  1. fgets写入sizeof(line)是否正确。我的疑问是line包含一个指针,所以它总是4或8个字节......
  2. line是否正确分配?

2 个答案:

答案 0 :(得分:2)

  1. 不,sizeof(line)将返回指针的大小。你真正想做的只是

    size_t size_required = strlen(user) + strlen(pass) + 1; /* Don't forget about \0! */
    

    然后只使用该大小作为行的大小。 (顺便说一句:你的代码没有自由行。)

    编辑:实际上,由于您最终想要读取由strtok搜索的用户+密码+ 2个令牌分隔符,您需要添加额外的3个字符:1用于终止\ 0,1用于第一个分隔符''和1表示下一个分隔符'\ n'。那应该是:

    size_t size_required = strlen(user) + strlen(pass) + 3; /* Don't forget about \0! */
    
  2. 您应该记住,动态分配的m说明符是非标准扩展名。它不适用于某些系统。如果他们的scanf调用返回正值,您应该发布userpass (如果他们成功了)。

  3. line的分配不正确:您分配的字符太少,因此终止\ 0字符将不适合(参见上文)。请注意,strlen返回字符串大小,不包括终止\ 0字符。

    此外,sizeof(char)毫无意义。标准保证sizeof(char)正好为1(因为sizeof并不真正返回字节数,而是覆盖参数位表示所需的字符数。)

  4. BONUS 您应该tmptmp2查看NULL,以防万一。在strcmp参数上调用NULL将导致分段错误。这是重要:如果读取的行包含比先前提供的更长的用户+密码,则fgets将无法读取标记分隔符,并且strtok无法找到,例如,最终的'\ n'字符,返回NULL。

答案 1 :(得分:0)

  

问:将值sizeof(line)写入fgets是否正确?

答:不:)

因为,正如你所说,它只有4(或8)个字节。

我完全不确定你要做什么。也许是这样的?

#define MAXLINE 80

char *user, *pass, line[MAXLINE];
scanf ("%s", line);
user = malloc(strlen(line)+1);
strcpy (user, line);
...