Reading of strings in C

2

I have a question regarding the reading of strings in C. I wrote this code and they corrected me the part where the text string is read. I previously had this written:

scanf("%10000[^\n]\n",texto);

and I think I did not really understand the entry of strings in C. If someone could explain to me what is the difference of the following two entries:

scanf("%10000[^\n]\n",texto); and scanf("%10000[^\n]s", texto); getchar();

and also what is the goal of using getchar() . If someone could answer these questions, I would greatly appreciate it. Greetings

#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>
int main(void)
{
    char texto[10001];
    char cadena[101];

    // ENTRADAS.

    scanf("%10000[^\n]s", texto);
    getchar();

    scanf("%100[^\n]s",cadena);

    //-----------------------Proceso-------------------------

    char *puntero = texto;

    unsigned short longitud = strlen(cadena);

    char auxiliar[10001];

    while ( (puntero = strstr(texto,cadena)) != NULL)
    {
        strcpy(auxiliar,"
scanf("%10000[^\n]\n",texto);
"); strncat(auxiliar, texto, puntero - texto); puntero = puntero + longitud; strcat(auxiliar,puntero); strcpy(texto, "
#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>
int main(void)
{
    char texto[10001];
    char cadena[101];

    // ENTRADAS.

    scanf("%10000[^\n]s", texto);
    getchar();

    scanf("%100[^\n]s",cadena);

    //-----------------------Proceso-------------------------

    char *puntero = texto;

    unsigned short longitud = strlen(cadena);

    char auxiliar[10001];

    while ( (puntero = strstr(texto,cadena)) != NULL)
    {
        strcpy(auxiliar,"%pre%");
        strncat(auxiliar, texto, puntero - texto);
        puntero = puntero + longitud;
        strcat(auxiliar,puntero);
        strcpy(texto, "%pre%");
        strcpy(texto,auxiliar);
    }

    printf("%s",texto);
    return 0;
}
"); strcpy(texto,auxiliar); } printf("%s",texto); return 0; }
    
asked by ocich93 03.10.2018 в 17:05
source

1 answer

4

A scanf() you have to pass as a first argument a format string that indicates the type of data you have to read. In your case, you read a string, so the format string would be (in principle) "%s" . It is the s that indicates s tring.

However "%s" poses two problems:

  • It will read characters until the first blank space is found and it will stop there (leaving the rest of the characters that the user had typed without reading, waiting for the next scanf() ). This is not normally what you want, since it would only allow you to read a word if the user had written several separated by spaces.
  • It is possible for the user to write more characters than we can save in the variable texto . scanf() does not check the limits of that variable (in fact you can not do it even if you want to, because all you receive is the address where the array texto starts, but not its size). If the user wrote more characters (without spaces) than they fit, the rest would overwrite other parts of the program memory, with the security risk that this entails (attacks by buffer overrun ). li>

    For both reasons, scanf() is not usually used to read lines of text, but fgets(texto, tamano_maximo, stdin) .

    In contrast, in your exercise, you have opted for a solution that, if I am frank, I had never seen and it would never have occurred to me, and it is to use as a format string "%10000[^\n]s" . This format string is still waiting for a s tring, for the s of the end, but all of the above gives indications to scanf() of what to expect. The number ( 10000 ) would be the maximum number of characters to read. That avoids the possible buffer overrun . The [^\n] indicates the category of characters to be supported, and is a kind of regular expression meaning "anything other than the character \n ".

    Therefore, that format string would read a complete line, with spaces and everything, stopping as soon as it finds a \n , or when it has read 10000 characters (whichever comes first).

    When the user types something, for example "Hello", and press carriage return, the character string "Hola\n" will be in the input buffer, since the carriage return entered by the user is coded as \n .

    Then scanf() will read all the characters up to \n (in this case four) and leave them in the array texto . The \n remains unread, waiting for the next instruction to read something from the standard input. It is for that \n that you make a getchar() , to "consume" it, otherwise it would be found by the next scanf() that you would do, which would confuse you and consider that the entry is a blank line.

    As I said before, this mess could be simplified a lot if you used:

    fgets(texto, 10000, stdin);
    

    since fgets() admits any sequence of letters (including spaces), has a parameter to specify the maximum to read, and also consumes the \n final avoiding the need of getchar() . The \n read would go to the variable texto , you could delete it with texto[strlen(texto)]=0; if you did not want it.

    By the way, your scanf("%10000[^\n]\n",texto); is not correct because the format string does not specify the type of data to be read.

        
  • answered by 03.10.2018 в 17:29