使用fgetc C从文件读取字符串的问题(不使用fscanf等)

时间:2015-05-16 23:41:13

标签: c realloc fgetc

我尝试只读取一个字符串,直到使用fgetc从文件中出现空格。我无法使用fscanf和其他i / o函数,因为我必须知道是否读取换行符。函数调用leerString(string,f)应该更改字符串变量内容,如果我将字符串打印到函数中,它会起作用,但在外部它的值是NONE。

当我尝试使用字符串变量更改返回值或传递" contador"时,我遇到了segmentation faults和其他realloc函数的错误。变量就像一个参考参数。这真让我抓狂。抱歉,英语不好。

char leerString(char *string, FILE *archivo){
    char caracter,caracter2 = 0;
    char *nombre = malloc(sizeof(char)*30);//works like a buffer
    int i = 0; 
    int j = 0;
    while (1){
        caracter = fgetc(archivo);
        if ((caracter != 32) && (caracter != EOF) && (caracter != '\n')){ 
            if (i < 30){
                nombre[i] = caracter;
            }
            else{
                nombre = realloc(nombre,30);
                if (nombre != NULL){
                    nombre[i] = caracter;
                }
                else{
                    printf("Error de asignacion de memoria\n");
                    exit(-2); 
                }
            }
            i++;
        }
        else{
            break;
        }
    }
    char *nombre2=malloc(sizeof(char)*i);//allocating the real size of the str
    for (j = 0; j<i; j++){ //cleaning the buffer
        caracter2 = nombre[j];
        nombre2[j] = caracter2;
    }   
    strcpy(string,nombre2);
    return caracter;    
}

1 个答案:

答案 0 :(得分:2)

我可以看到您的代码存在很多问题

  1. 您正在使用realloc()重新分配相同大小的缓冲区;它意味着调整缓冲区的大小。
  2. 您的caracter变量的类型为char,但fgetc()返回int
  3. 您为目标字符串分配内存,然后如上所述不必要地使用realloc(),然后再次分配空间,并执行此操作

    for (j = 0; j<i; j++){ //cleaning the buffer
        caracter2 = nombre[j];
        nombre2[j] = caracter2;
    }   
    

    除了

    之外什么都不做
    memcpy(nombre2, nombre, i);
    
  4. 您没有为终止nul字节分配空间,因此strcpy()会在您的代码中失败,从而导致分段错误或其他任何问题,因为它的未定义行为

  5. 您还应该确保string有足够的空间将字符复制到其中,或者只返回指向函数中malloc() ed字符串的指针,该字符串返回char而且我不知道这是否有用,因为你没有发布足够的代码来告诉你。

    更好的解决方案是

    char *
    leerString(char *string, size_t size, FILE *archivo)
    {
        int    chr;
        size_t i;
    
        i   = 0;
        chr = fgetc(archivo);
        while ((chr != EOF) && (isspace(chr) == 0) && (i < size - 1))
        {
            string[i++] = chr;
            chr         = fgetc(archivo);
        }
        if (i == 0)
            return NULL;
        string[i] = '\0'; /* ensure it's `nul' terminated */
    
        return string;
    }
    

    您可以使用如下

    char string[100];
    
    if (leerString(string, sizeof(string), archivo) != NULL)
        printf("%s\n", string);