4

Given a user input of unknown length (consisting of words with maximum length 100). Is there a way to read it dynamically string by string?

It is my understanding that scanf reads a string until a space is reached, so I tried using scanf but it enters an infinite loop.

char buf[101];
while (scanf("%s", buf))
{
    //something is done with the string
}
Andre Kampling
  • 5,476
  • 2
  • 20
  • 47
lezlemon
  • 61
  • 1
  • 1
  • 5

3 Answers3

8

Given a user input of unknown length (consisting of words with maximum length 100) is there a way to read it dynamically string by string?

Building your own function, instead of scanf would help to achieve this

  • Here, I've created a function scan which would dynamically take in the string by increasing it's size over each iteration

  • I've use the additional header files string.h and stdlib.h for the following reasons :

    1. functions in stdlib.h (click to know more) library file are useful for dynamic allocation of memory.

    2. functions in string.h (click to know more) library file are useful to handle strings.

Note: the input from the user stops when he enters the string end.

#include <stdio.h>  //the standard library file
#include <stdlib.h> //library file useful for dynamic allocation of memory
#include <string.h> //library file with functions useful to handle strings

//the function    
char* scan(char *string)
{
    int c; //as getchar() returns `int`
    string = malloc(sizeof(char)); //allocating memory

    string[0]='\0';

    for(int i=0; i<100 && (c=getchar())!='\n' && c != EOF ; i++)
    {
        string = realloc(string, (i+2)*sizeof(char)); //reallocating memory
        string[i] = (char) c; //type casting `int` to `char`
        string[i+1] = '\0'; //inserting null character at the end
    }

    return string;
}

int main(void)
{
    char *buf; //pointer to hold base address of string

    while( strcmp((buf=scan(buf)),"end") ) //this loop will continue till you enter `end`
    {
        //do something with the string

        free(buf); //don't forget to free the buf at the end of each iteration
    }

    free(buf); //freeing `buf` for last input i.e, `end` 

}

let's just //do something with the string to see whether the above code works or not :)

I change the following while loop in main function :

    while( strcmp((buf=scan(buf)),"end") )
    {
        //do something with the string
    }

to

while( strcmp((buf=scan(buf)),"end") )
{
    printf("you entered : %s\n",buf);
    printf("size        : %u\n",strlen(buf));
    printf("reversing   : %s\n",strrev(buf));

    printf("\n-------------------\n");

    free(buf);
}

and now,

input :

hall
of
fame
stay in it
end

output :

you entered : hall
size        : 4
reversing   : llah

-------------------
you entered : of
size        : 2
reversing   : fo

-------------------
you entered : fame
size        : 4
reversing   : emaf

-------------------
you entered : stay in it
size        : 10
reversing   : ti ni yats

-------------------

Cherubim
  • 5,287
  • 3
  • 20
  • 37
  • 1
    Not a real concern for OP, but consider `i<100 && (c=getchar())!='\n'` instead of `(c=getchar())!='\n' && i<100`. If there is no room, why read and throw away a character? Better to read it next time. – chux - Reinstate Monica Jul 05 '16 at 21:25
  • 1
    `EOF` indicates an input error or end-of-file occurred (no more input). The read loop should have 3 ending conditions: `i<100 && (c=getchar())!='\n' && c != EOF`. Else on end-of-file, code will continually read 100 `EOF`. This also implies `strcmp((buf=scan(buf)),"end")` is a problem. What happens if `"end"` does not exist? How does the calling code distinguish between a line of only `"\n"` and end-of-file? Good luck +1. – chux - Reinstate Monica Jul 05 '16 at 21:33
2

I found a solution!

while (scanf("%s%c", buf, &c))
    {
        //do something with the string
        if (c == '\n') break;
    }
lezlemon
  • 61
  • 1
  • 1
  • 5
  • 1
    What happens when `scanf("%s%c", buf, &c)` returns 1 or `EOF`? Is `if (c == '\n')` safe to execute? – chux - Reinstate Monica Jul 05 '16 at 21:13
  • Unclear why code stops at `'\n'` as the post said "Given a user input of unknown length", there maybe be many lines of input. – chux - Reinstate Monica Jul 05 '16 at 21:19
  • `Is there a way to read it dynamically string by string?` but your solution to your question is not dynamical.. @lezlemon – Cherubim Jul 06 '16 at 02:59
  • @CherubimAnand maybe I didn't make myself clear, it reads strings until it reaches '\n' which is what I wanted. The maximum length of the individual strings is known, but their number is not. – lezlemon Jul 06 '16 at 11:13
  • @chux I should have been more clear. The input will always be strings (words) separated by a space, until it reaches '\n', so c will be equal to ' ' until the end of the line is reached, which is the end of the input, for my purposes. – lezlemon Jul 06 '16 at 11:14
  • Information like that buried in one of the answers does not change the post. That new information belongs there. – chux - Reinstate Monica Jul 06 '16 at 13:01
0

I think you need something like this.

while (scanf("%s", code) == 1)
{
    // no need for second scanf call
    // do whatever you like here
}  

Edit: Try this.

freopen("input.txt","r",stdin);
//Above line makes program to take input from file.
//File should be present in same folder
char c[50];
while(scanf("%s",c)!=EOF)
{
    printf("%s\n",c);
}
dazzieta
  • 662
  • 4
  • 20