How to input multi-word string in C - c

I have this program. I want to input multi-word strings in a 2-D array. But instead of input whole string in first array of 2-D array this program inputs the first three words of my String in the first three array each(as I defined the no of rows in my 2-D array). Here is the program:
int main()
{
char title[50];
int track;
int question_no;
printf("\nHow many questions?\t");
scanf("%d",&question_no);
track=0;
char question[question_no][100];
while(track<=question_no)
{
printf("Question no %d is:",track+1);
scanf("%s",question[track]);
printf("Q %d.%s",track,question[track]);
track++;
}
}
Here "question_no" is the no of strings I want to input in my 2-D array- "question". But when I input first string, the string's first three words get inputted in the three arrays of 2-D array. It even doesn't ask me to input 2nd or 3rd strings.
A solution to this problem, as I perceive, should be 3-D array. Because that way 2-D arrays inside the outermost array would print the whole multi-word string (But there too I am bound to the length of each string, I think). If this, 3-D array concept, can solve the problem, then is there some efficient method also? Which is better, faster and less time consuming than 3-D array method.

scanf("%s") will scan a string up to the first piece of white space it finds, hence it's unsuitable for multi-word input.
There are ways to use scanf for line-based input but you're generally better off using methods that are easier to protect from buffer overflow, such as an old favorite of mine:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
This is a handy routine which provides line-based input, buffer overflow protection, detection of lines that are too long, cleaning up of those lines so that they don't affect the next input operation and prompting.
A test program can be seen below:
int main (void) {
int rc;
char buff[10] = "";
while ( 1) {
rc = getLine ("\nWhat? ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
continue;
}
if ( strcmp (buff, "exit") == 0)
break;
printf ("OK [%s]\n", buff);
}
return 0;
}
And a transcript follows:
pax> ./testprog
What? hello
OK [hello]
What? this is way too big for the input buffer
Input too long [this is w]
What?
OK []
What? exit
pax> _

Use gets(), this takes input as one string including white spaces, even the newline. But will take in till the first newline. As opposed to scanf(), which takes upto the first white space.

Related

Extreme troubles with full line input. C Programming Language

I am having the absolute craziest time getting full line input to work. I will explain my problem. I need to get a full line of input, including a space, from the user entered at the keyboard. Simple right? Wrong!
MY GOAL
Store multiple strings, with spaces, into variables. If it makes a difference, I want to make the variables equal to a char pointer. So once I get the input from tempString, I want to set it to a char pointer. Like so:
char *variable1, *variable2;
//get user input
variable1 = tempString;
//get more user input
variable 2 = tempString;
//etc etc etc
Here's what I've tried.
First try
char tempString[100];
scanf("%s", &tempString);
printf("%s", tempString);
Invalid: scanf will stop reading at a white space, so "Example String" would just end up being "Example".
Second try
So I do more research. I thought I found the magic fix.
char tempSTring[100];
fgets(tempString, 100, stdin);
printf("%s", tempString);
Originally this works. However there is a massive problem. I need to get the user to enter about 8 inputs. Meaning I have to use a command like this 8 times. The problem is the program often skips over the fgets command. If I use a scanf previously, somehow the \n character is stuck in the input stream, and automatically feeds into fgets, satisfying its stdin input, and then does not prompt the user for input.
Third try
After thinking fgets was maybe my solution with a work around, I tried some tricks.
char tempSTring[100];
getc(stdin);
fgets(tempString, 100, stdin);
printf("%s", tempString);
I tried adding this getc(stdin) line. It worked for much of my program. It absorbs the \n character left behind in the stream. When it does so, great, it works. But sometimes, for some reason, the \n is NOT left in the stream, and when debugging, it looks like getc(stdin) is requesting input from the user, so it pauses my program to ask for input.
Question
These don't work for me.
How should I be doing this easy task?
To read (up to) 8 lines from a file, you can use either of these solutions. I decline to use variables char *variable1, *variable2, …; — that is an array seeking to escape.
POSIX getline()
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
enum { MAX_LINES = 8 };
char *lines[MAX_LINES];
int index = 0;
char *buffer = 0;
size_t buflen = 0;
while (index < MAX_LINES && getline(&buffer, &buflen, stdin) != -1)
{
lines[index++] = buffer;
buffer = 0;
buflen = 0;
}
free(buffer); // Space may be allocated before EOF is detected
for (int i = 0; i < index; i++)
printf("%d: %s", i, lines[i]);
return 0;
}
If getline() fails to allocate memory, it will report an error, so there is no need to do an explicit error check.
Standard C fgets()
Code using strdup(), another POSIX function. It isn't a part of standard C (though it is widely available). It is trivial to implement.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
enum { MAX_LINES = 8 };
char *lines[MAX_LINES];
int index = 0;
char buffer[4096];
while (index < MAX_LINES && fgets(buffer, sizeof(buffer), stdin) != 0)
{
if ((lines[index] = strdup(buffer)) == 0)
break;
index++;
}
for (int i = 0; i < index; i++)
printf("%d: %s", i, lines[i]);
return 0;
}
The test in the loop allows for the possibility of strdup() failing to allocate memory.
Notes
Both the solutions above keep the newline at the end of the input string. If you don't want that, you can zap it with:
lines[i][strcspn(lines[i], "\r\n")] = '\0';
This overwrites a carriage return or newline with a null byte, transforming DOS or Unix line endings. You then need to adjust the printing which assumes the string includes a newline. Note that the expression shown works correctly even if there is no carriage return or newline in the string.
The fgets() solution will break lines at 4095 characters, leaving the rest to be read as 'the next line'. If that's not acceptable, you have a variety of strategies open to you.
You can detect whether there is a newline and arrange to allocate more memory and read the next section of the line into the extra memory, repeating until you come across a newline or EOF.
You can read the remaining characters up to the newline or EOF:
int c;
while ((c = getchar()) != EOF && c != '\n')
;
Implementing strdup()
If for some reason your system doesn't have an implementation of strdup(), you can create a surrogate with:
#include <assert.h>
#include <stdlib.h>
#include <string.h>
char *strdup(const char *old_str)
{
assert(old_str != 0);
size_t old_len = strlen(old_str) + 1;
char *new_str = malloc(old_len);
if (new_str != 0)
memmove(new_str, old_str, old_len);
return new_str;
}
Here's how we old fart C programmers would do it:
#include <stdio.h>
#define MAX_LEN 100
int main( )
{
int c;
char input[MAX_LEN+1];
int i = 0;
while ( (c=getchar()) != '\n' && c != EOF && i < MAX_LEN)
input[i++] = c;
if (c == EOF || c =='\n') {
/* received input that terminated within buffer limit */
input[i] = '\0';
printf("read in your input string of: %s\n", input);
}
else {
printf("don't buffer overflow me dude!\n");
return -1;
}
return 0;
}
But nowadays people will tell you to use one of the library functions. I'm still an old fart though.
EDIT: Fixed my embarrassing mistakes pointed out by the helpful comments below.
You can take care of '\n' left by previous scanf by writing it like this -
scanf("%d%*c", &x); //<-- example to take int input
%*c will read from stdin and then discard it, thus '\n' would be removed from stdin.
You can achieve with scanf like this (a way for your previous attempt)-
char tempString[100];
/* As suggested by chqrile it is essential to check return of scanf */
if(scanf("%99[^\n]", tempString)!=1){
// ^^ & not required
tempString[0]='\0';
}
%99[^\n] this will read 99 characters and will stop only after encountering '\n' , thus would read input with spaces.

How to take a line input in C?

I was trying to take a full line input in C. Initially I did,
char line[100] // assume no line is longer than 100 letters.
scanf("%s", line);
Ignoring security flaws and buffer overflows, I knew this could never take more than a word input. I modified it again,
scanf("[^\n]", line);
This, of course, couldn't take more than a line of input. The following code, however was running into infinite loop,
while(fscanf(stdin, "%[^\n]", line) != EOF)
{
printf("%s\n", line);
}
This was because, the \n was never consumed, and would repeatedly stop at the same point and had the same value in line. So I rewrote the code as,
while(fscanf(stdin, "%[^\n]\n", line) != EOF)
{
printf("%s\n", line);
}
This code worked impeccably(or so I thought), for input from a file. But for input from stdin, this produced cryptic, weird, inarticulate behavior. Only after second line was input, the first line would print. I'm unable to understand what is really happening.
All I am doing is this. Note down the string until you encounter a \n, store it in line and then consume the \n from the input buffer. Now print this line and get ready for next line from the input. Or am I being misled?
At the time of posting this question however, I found a better alternative,
while(fscanf(stdin, "%[^\n]%*c", line) != EOF)
{
printf("%s\n", line);
}
This works flawlessly for all cases. But my question still remains. How come this code,
while(fscanf(stdin, "%[^\n]\n", line) != EOF)
{
printf("%s\n", line);
}
worked for inputs from file, but is causing issues for input from standard input?
Use fgets(). #FredK
char buf[N];
while (fgets(buf, sizeof buf, stdin)) {
// crop potential \n if desired.
buf[strcspn(buf, "\n")] = '\0';
...
}
There are to many issues trying to use scanf() for user input that render it prone to mis-use or code attacks.
// Leaves trailing \n in stdin
scanf("%[^\n]", line)
// Does nothing if line begins with \n. \n remains in stdin
// As return value not checked, use of line may be UB.
// If some text read, consumes \n and then all following whitespace: ' ' \n \t etc.
// Then does not return until a non-white-space is entered.
// As stdin is usually buffered, this implies 2 lines of user input.
// Fails to limit input.
scanf("%[^\n]\n", line)
// Does nothing if line begins with \n. \n remains in stdin
// Consumes 1 char after `line`, even if next character is not a \n
scanf("%99[^\n]%*c", line)
Check against EOF is usual the wrong check. #Weather Vane The following, when \n is first entered, returns 0 as line is not populated. As 0 != EOF, code goes on to use an uninitialized line leading to UB.
while(fscanf(stdin, "%[^\n]%*c", line) != EOF)
Consider entering "1234\n" to the following. Likely infinite loop as first fscanf() read "123", tosses the "4" and the next fscanf() call gets stuck on \n.
while(fscanf(stdin, "%3[^\n]%*c", line) != EOF)
When checking the results of *scanf(), check against what you want, not against one of the values you do not want. (But even the following has other troubles)
while(fscanf(stdin, "%[^\n]%*c", line) == 1)
About the closest scanf() to read a line:
char buf[100];
buf[0] = 0;
int cnt = scanf("%99[^\n]", buf);
if (cnt == EOF) Handle_EndOfFile();
// Consume \n if next stdin char is a \n
scanf("%*1[\n]");
// Use buf;
while(fscanf(stdin, "%[^\n]%*c", line) != EOF)
worked for inputs from file, but is causing issues for input from standard input?
Posting sample code and input/data file would be useful. With modest amount of code posted, some potential reasons.
line overrun is UB
Input begins with \n leading to UB
File or stdin not both opened in same mode. \r not translated in one.
Note: The following fails when a line is 100 characters. So meeting the assumption cal still lead to UB.
char line[100] // assume no line is longer than 100 letters.
scanf("%s", line);
Personally, I think fgets() is badly designed. When I read a line, I want to read it in whole regardless of its length (except filling up all RAM). fgets() can't do that in one go. If there is a long line, you have to manually run it multiple times until it reaches the newline. The glibc-specific getline() is more convenient in this regard. Here is a function that mimics GNU's getline():
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long my_getline(char **buf, long *m_buf, FILE *fp)
{
long tot = 0, max = 0;
char *p;
if (*m_buf == 0) { // empty buffer; allocate
*m_buf = 16; // initial size; could be larger
*buf = (char*)malloc(*m_buf); // FIXME: check NULL
}
for (p = *buf, max = *m_buf;;) {
long l, old_m;
if (fgets(p, max, fp) == NULL)
return tot? tot : EOF; // reach end-of-file
for (l = 0; l < max; ++l)
if (p[l] == '\n') break;
if (l < max) { // a complete line
tot += l, p[l] = 0;
break;
}
old_m = *m_buf;
*m_buf <<= 1; // incomplete line; double the buffer
*buf = (char*)realloc(*buf, *m_buf); // check NULL
max = (*m_buf) - old_m;
p = (*buf) + old_m - 1; // point to the end of partial line
}
return tot;
}
int main(int argc, char *argv[])
{
long l, m_buf = 0;
char *buf = 0;
while ((l = my_getline(&buf, &m_buf, stdin)) != EOF)
puts(buf);
free(buf);
return 0;
}
I usually use my own readline() function. I wrote this my_getline() a moment ago. It has not been thoroughly tested. Please use with caution.

Is this vulnerable to a stack overflow?

void gctinp (char *inp, int siz)
{
puts ("Input value: ");
fgets (inp, siz, stdin);
printf ("buffer3 getinp read %s", inp);
}
From what I've read, fgets is supposed to be used when you want to limit the size of input. So this code shouldn't be vulnerable right?
It is being called like so:
int main (int argc, char *argv[])
{
char buf[16];
getinp (buf, sizeof (buf));
display (buf);
printf ("buffer3 done\n");
}
Thanks for your time.
You won't strike buffer overflow problems if you enter more characters than can be safely stored since fgets restricts the input. It also adds a null terminator (assuming buffer size is greater than 0, of course).
However, you will have problems with information being left in the input buffer the next time you try to read something - this is something that users will find very annoying, entering something like hello again and having it treated as two separate inputs like hello ag and ain. And there's no indication given by fgets that it stopped retrieving input before the end of the line so, as far as your code is aware, everything is fine.
The major things you need to look out for (re buffer overflows on input) are, at a minimum, scanf with an unbounded %s format string and gets, which has no limiting size argument, neither of which are in your code.
If you're looking for a more robust input solution with size limiting, prompting and buffer clearing, check out this code, which provides all those features:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
// Test program for getLine().
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
rc = getLine ("Hit ENTER to check remains> ", buff, sizeof(buff));
printf ("Excess [%s]\n", buff);
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
And, doing some basic tests:
pax> ./prog
Enter string> [CTRL-D]
No input
pax> ./prog
Enter string> x
OK [x]
pax> ./prog
Enter string> hello
OK [hello]
pax> ./prog
Enter string> hello from earth
Input too long [hello fro]
Hit ENTER to check remains> [ENTER]
Excess []
pax> ./prog
Enter string> i am pax
OK [i am pax]
No, it isn't prone to stack overflow.
Are you confusing stack overflow and buffer overflow by any chance?
http://en.wikipedia.org/wiki/Stack_overflow
fgets will read at most one less than the specified number of bytes, and will make sure that the read string is null-terminated. So as long as you pass the correct size, it should be fine (although the string might not end in a newline).

Handling String input in C

If a char array needs to be declared before it is used, how does one declare one so that is can be used to store input?
e.g. The user enters a sentence or series of words. How is this stored so that it can be manipulated?
What is the correct way rather than just declaring an array which is large enough to handle expected input?
If you are talking about console input, you have no choice but to have a FIXED SIZE buffer and use a secure function not allowing more than FIXED_SIZE to be stored on your buffer.
An example would be:
char buff[1024];
fgets(buff, 1024, stdin); // to read from standard input
You must warn your user that any characters beyond 1023th will be ignored.
If you want to access last character the user entered:
printf("%c", buff[strlen(buff)-1]);
I usually use the following function:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
It uses the buffer-overflow-safe fgets with some supporting code to figure out if the line you entered was too long.
You can of course, read partial lines and perform memory re-allocations to store an arbitrary sized input string but usually it's more than adequate to just set a large enough upper boundary and allow for that (say 1K for example). If anyone enters more than that for their name or address, they're probably just being silly :-)
I've actually used that trick (partial reads and reallocs) to do user input before but, to be honest, the need for it was so rare that it didn't make it into my "important source code snippets" repository.
The use of fgets prevents the possibility of buffer overflow which is the big danger to user input.
If you want to test that code, try adding:
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
printf ("No input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long\n");
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
and some sample runs:
pax> ./qq
Enter string> hi bob
OK [hi bob]
pax> ./qq
Enter string>
No input
pax> ./qq
Enter string> hi ho the merry oh
Input too long
(that second one was entering CTRLD, an immediate end of file).
Input via buffer ? ( User writes its text to buffer of some size, when buffer is full, programm changes size of target array using realloc )
( you need to use char* instead of char[] )

C - Malloc issue (maybe something else)

Update edition:
So, I'm trying to get this code to work without using scanf/fgets. Gets chars from the user, puts it into a pointer array using a while loop nested in a for loop.
#define WORDLENGTH 15
#define MAXLINE 1000
int main()
{
char *line[MAXLINE];
int i = 0;
int j;
int n;
char c;
for (n=0; c!=EOF; n){
char *tmp = (char *) malloc(256);
while ((c=getchar())!=' '){
tmp[i]=c; // This is no longer updating for some reason.
i++;
}
line[n++]=tmp; //
i=0;
printf("\n%s\n",line[n]); //Seg fault here
}
for(j = 0; j (lessthan) n; j++){
printf("\n%s\n", line[j]);
free (line[j]);
}
return 0;
So, now I'm getting a seg fault. Not sure why tmp[i] is not updating properly. Still working on it.
I've never learned this much about programming during the entire semester so far. Please keep helping me learn. I'm loving it.
You print line[i] and just before that, you set i to 0. Print line[n] instead.
Also, you forgot the terminating 0 character. And your code will become easier if you make tmp a char array and then strdup before assigning to line[n].
sizeof(WORLDLENGTH), for one, is wrong. malloc takes an integer, and WORLDLENGTH is an integer. sizeof(WORLDLENGTH) will give you the size of an integer, which is 4 if you compile for a 32-bit system, so you're allocating 4 bytes.
Btw - while ((c=getchar())!=' '||c!=EOF) - what's your intent here? A condition like (a!=b || a!=c) will always return true if b!=c because there is no way a can be both b and c.
And, as others pointed out, you're printing out line[i], where i is always 0. You probably meant line[n]. And you don't terminate the tmp string.
And there's no overflow checking, so you'll run into evil bugs if a word is longer than WORDLENGTH.
Others have already told you some specific problems with your code but one thing they seem to have missed is that c should be an int, not a char. Otherwise the comparison to EOF wil not work as expected.
In addition, the segfault you're getting is because of this sequence:
line[n++]=tmp;
printf("\n%s\n",line[n]);
You have already incremented n to the next array element then you try to print it. That second line should be:
printf("\n%s\n",line[n-1]);
If you just want some code that works (with a free "do what you darn well want to" licence), here's a useful snippet from my code library.
I'm not sure why you think fgets is to be avoided, it's actually very handy and very safe. I'm assuming you meant gets which is less handy and totally unsafe. Your code is also prone to buffer overruns as well, since it will happily write beyond the end of your allocated area if it gets a lot of characters that are neither space nor end of file.
By all means, write your own code if you're educating yourself but part of that should be examining production-tested bullet-proof code to see how it can be done. And, if you're not educating yourself, you're doing yourself a disservice by not using freely available code.
The snippet follows:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
// Test program for getLine().
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
printf ("No input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long\n");
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
It's a useful line input function that has the same buffer overflow protection as fgets and can also detect lines entered by the user that are too long. It also throws away the rest of the too-long line so that it doesn't affect the next input operation.
Sample runs with 'hello', CTRLD, and a string that's too big:
pax> ./qq
Enter string> hello
OK [hello]
pax> ./qq
Enter string>
No input
pax> ./qq
Enter string> dfgdfgjdjgdfhggh
Input too long
pax> _
For what it's worth (and don't hand this in as your own work since you'll almost certainly be caught out for plagiarism - any half-decent educator will search for your code on the net as the first thing they do), this is how I'd approach it.
#include <stdio.h>
#include <stdlib.h>
#define WORDLENGTH 15
#define MAXWORDS 1000
int main (void) {
char *line[MAXWORDS];
int numwords = 0; // Use decent variable names.
int chr, i;
// Code to run until end of file.
for (chr = getchar(); chr != EOF;) { // First char.
// This bit gets a word.
char *tmp = malloc(WORDLENGTH + 1); // Allocate space for word/NUL
i = 0;
while ((chr != ' ') && (chr != EOF)) { // Read until space/EOF
if (i < WORDLENGTH) { // If space left in word,
tmp[i++] = chr; // add it
tmp[i] = '\0'; // and null-terminate.
}
chr = getchar(); // Get next character.
}
line[numwords++] = tmp; // Store.
// This bit skips space at end of word.
while ((chr == ' ') && (chr != EOF)) {
chr = getchar();
}
}
// Now we have all our words, print them.
for (i = 0; i < numwords; i++){
printf ("%s\n", line[i]);
free (line[i]);
}
return 0;
}
I suggest you read that and studdy the comments so that you know how it's working. Feel free to ask any questions in the comments section and I'll answer or clarify.
Here's a sample run:
pax$ echo 'hello my name is pax andthisisaverylongword here' | ./testprog
hello
my
name
is
pax
andthisisaveryl
here
Change your printf line - you need to print line[n] rather than line[i].
first your malloc formula is wrong
malloc(sizeof(char)*WORDLENGTH);
you need to allocate the sizeof a char enought times for the lenght of your word (also 15 seems a bit small, your not counting the longest word in the dictionnary or the "iforgettoputspacesinmyphrasestoscrewtheprogrammer" cases lol
don't be shy char is small you can hit 256 or 512 easily ^^
also
printf("\n%s\n",line[i]);
needs to be changed to
int j = 0;
for(j=0;j<i;j++){
printf("\n%s\n",line[j]);
}
your i never changes so you always print the same line

Resources