How to read string with space in a repeat structure?

Asked

Viewed 4,985 times

0

I have to make a program to read the name, the author and the price of an n quantity of books (from structures). I made a struct for the books that way :

typedef struct{
    char nome[100];
    char autor[100];
    float preco;
}dadoslivros;

and created a variable databooks to be able to read the information of the different books.

dadoslivros livros[100];

however when trying to read strings name or author I cannot read with spaces. I have tried:

for (i = 0; i < qtdlivros;i++){
    scanf("%s",livros[i].nome);
    scanf("%s",livros[i].autor);
    scanf("%f",&livros[i].preco);  
}

but this way I read only names or authors without space, if you put a space in the name that comes after the space goes to "authors" and if you put space in the author, what comes after the space goes to "price", then I tried this way :

for (i = 0; i < qtdlivros;i++){
    scanf ("%[^\n],livros[i].nome);
    scanf ("%[^\n],livros[i].autor);
    scanf ("%f",&preco);
}

But that way it doesn’t even enter the reading. I would like to know why this happens and how to read the name and the author with space.

  • See if it helps you: https://answall.com/q/177409/101, https://answall.com/q/42981/101 and https://answall.com/q/109966/101

  • Thanks, but unfortunately none helped me because due to the limitations of the exercise I can not use the library "string. h". And this was the only way q vi to solve my problem (using fgets() ) from the links q sent me

  • I can’t imagine what one has to do with the other.

  • The only way I could solve my problem from the links you sent me was using the function fgets(), which for this exercise does not serve because it is a college exercise and I can not use functions like fgets ().

  • 1

    Oh so I don’t even waste time, these weird requirements don’t serve to teach anything useful, unless it was time to read all raw anyway, and even scanf could use, because the goal would be to train the data entry algorithm

2 answers

0

You can quickly solve your problem by consuming all the buffer so that the "n" doesn’t get in the way of other readings.

a method that works very well is this:

void flush_in(){ 
int ch;
while( (ch = fgetc(stdin)) != EOF && ch != '\n' ){} 
}

this way you could leave your code in this same format:

int main(){
char nome[100],autor[100];
float preco;

while(1){
    scanf("%[^\n]",nome);
    flush_in();
    scanf("%[^\n]",autor);
    flush_in();
    scanf ("%f",&preco);

    printf("\n%s %s %f\n",nome,autor,preco);
}

return 0;
}

0

Your problem when it comes to using the scansets (the name of those structures "%[^\n]") is that, as you imagine, in time for him to pick up the first item he reads until the first car return, but does not read the return car. Then, in the second, he tries to read until the next car return and, what a coincidence! , the first character it reads is a car return. So it doesn’t put anything in the second variable.

What you need to do is put the return car after yours scanset there in the format string:

for (i = 0; i < qtdlivros; i ++) {
    scanf("%99[^\n]\n",livros[i].nome);
    scanf("%99[^\n]\n",livros[i].autor);
    scanf("%f",&livros[i].preco);
}

But as you will not put prompts asking for each value, you can save by concatenating all the format strings:

for (i = 0; i < qtdlivros; i ++) {
    scanf(
        "%99[^\n]\n%99[^\n]\n%f",
        livros[i].nome,
        livros[i].autor,
        &livros[i].preco
    );
}

Note the 99 I put between the % and the [: it is a sub-specialist of maximum reading length. This prevents the scanf() try to write more than 99 characters on autor or in the nome (have to save a character to the null byte). This type of detail is very important to avoid the error class called buffer overrun, which is a recurring theme in C programming.

  • So... I did it this way but when I run the program goes straight to the price of the book, does not enter the reading of the name nor the author.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.