function call in do while loop only execute once. - c

I had a program to check user input and make sure it's only integer and not character. In my main function, do while loop only executes once when the input is incorrect. But I want it to keep it executing until the user enter a valid input. My doAgain() function is to ask if the user want to Try again or not. The problem is with doAgain() function. It only executes once if leave it in the if statement. Everything works fine except this glitch. However, when i remove it, the loop keep executing until the user enter valid input like i wanted it to, but then doAgain() function would be useless
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* get boundary */
char* getBoundary(char str[]){
int i;
char c;
str = (char*) malloc(sizeof(char));
for (i = 0; (c = getchar()) != '\n'; i++) // The loop stop running after the second time
{
str = (char *) realloc(str, sizeof(char) + i);
str[i] = c;
}
str[i] = '\0';
return str;
}
/* check for valid string */
int checkStr(const char *check)
{
unsigned i;
size_t len = strlen(check);
for (i = 0; i < len; i++)
if(isalpha(check[i]))
{
printf("Invalid integer formatt!!!");
return 0;
}
return 1;
}
/* Ask if do again */
int doAgain(void)
{
char ans, c;
do {
printf("Do you want to try again?: ");
scanf(" %c", &ans);
switch (ans)
{
case 'y':
case 'Y':
case 'n':
case 'N':
return (ans == 'y') || (ans == 'Y') ? 1 : 0;
break;
default:
printf("Invalid answer!!! answer 'y' and 'Y' or 'n' and 'N' only\n");
do { /* flush input stream */
c = getchar();
}while (c != '\n');
}
}while (1);
}
/* Main */
int main(void)
{
char *l_boundRow;
l_boundRow = NULL;
do {
printf("Enter lower bound row: ");
l_boundRow = getBoundary(l_boundRow);
if (!checkStr(l_boundRow) && doAgain()) // problem start here, it works if I remove doAgain() function
continue; // if the string is invalid, the program asks user if they want to try again
else
break;
}while (1);
free(l_boundRow);
return 0;
}

Revised answer
The immediate problem is that when doAgain() exits with y or n, it doesn't read the newline after those characters, so when it re-enters getBoundary(), the first character it reads is whatever was after the y or n which was probably a newline, which terminates the input line. You need to gobble the rest of the line on a valid input as well as on the invalid ones.
This code mostly works — it is leak free, too (at least under my casual testing).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char* getBoundary(void);
int checkStr(const char *check);
int doAgain(void);
/* get boundary */
char* getBoundary(void)
{
int i;
int c;
char *str = (char*) malloc(sizeof(char));
for (i = 0; (c = getchar()) != '\n' && c != EOF; i++)
{
str = (char *) realloc(str, 2 + i);
str[i] = c;
}
str[i] = '\0';
return str;
}
/* check for valid string */
int checkStr(const char *check)
{
unsigned i;
size_t len = strlen(check);
for (i = 0; i < len; i++)
{
if (!isdigit(check[i]))
{
printf("Invalid integer format (%s)!!!\n", check);
return 0;
}
}
return 1;
}
static int gobble(void)
{
int c;
while ((c = getchar()) != EOF && c != '\n')
;
return c;
}
/* Ask if do again */
int doAgain(void)
{
char ans;
int c;
do {
printf("Do you want to try again?: ");
scanf(" %c", &ans);
switch (ans)
{
case 'y':
case 'Y':
c = gobble();
return 1;
case 'n':
case 'N':
c = gobble();
return 0;
default:
{
printf("Invalid answer!!! answer 'y' and 'Y' or 'n' and 'N' only\n");
c = gobble();
if (c == EOF)
{
printf("EOF detected\n");
return 0;
}
}
}
} while (1);
}
/* Main */
int main(void)
{
char *l_boundRow;
l_boundRow = NULL;
do {
printf("Enter lower bound row: ");
l_boundRow = getBoundary();
if (checkStr(l_boundRow))
break;
if (!doAgain())
break;
free(l_boundRow);
}while (1);
printf("Final bound row: %s\n", l_boundRow);
free(l_boundRow);
return 0;
}
If you select not to try again after an invalid input, the last invalid value is printed as the 'Final bound row'. You can easily hack the code to avoid that problem.
Incidentally, when I first compiled your code, I only got 3 warnings from it under my default stringent options — because I demand prototypes before (non-static) function definitions. That's extremely good; well done. Few people write code that's posted on SO that passes that level of scrutiny with as few complaints.
If it were my code, I would have few if any do … while loops (none in this code). They are occasionally useful, but occasionally is the operative term. Generally, it is best to use a top-testing while loop, or an explicit for loop.
Original answer
A real problem, but not the one immediately causing trouble.
In the code in getBoundary(), you first allocate one character. Then, in the body of the loop, you reallocate i + 1 characters. On the first iteration, you reallocate 1 byte; then 2, etc. And then when you exit the loop, you write one beyond the last character that was allocated, which leads to undefined behaviour. You need to use i + 2 as the size to reallocate. (There are those who'd rail against you for using sizeof(char) since that is guaranteed to be 1.)
That is probably the source of your trouble; writing beyond the end of an allocated buffer can easily lead to crashes.
If you ran the code under valgrind, it would tell you about this mistake.
Separately, it is not a good idea to allocate one more byte each time around the loop. It would be better to allocate, say, 20 bytes (big enough to hold any 64-bit integer value), or to double the size on each iteration when you need more space. It isn't going to be time critical in this context, but it can become a problem in bigger programs.
Note too that your checkstr() function only detects alpha characters; punctuation and control characters will also not convert to an integer. You should check that each character is a digit (isdigit(check[i])), and you might have to worry about plain char being signed — so isdigit((unsigned char)check[i]) is better still. Similar comments apply to the other isuvwxyz() functions.
In doAgain(), you should use int c; instead of char c; and you should check for EOF as well as newline. If you detect EOF, the answer is 'no' and you should return that.
Also, in your getBoundary() function again, you have:
str = (char *) realloc(str, sizeof(char) + i);
There are those who would castigate you for the cast; I am not of the mindset that does that. But be aware that you will get criticism for doing so from many people who answer questions on C at SO.
More significantly, you should not write the realloc() code this way. The idiom:
ptr = realloc(ptr, new_size);
leaks memory if the allocation fails. You've just had the only pointer to the memory wiped out with NULL, even though realloc() promises that it did not free the old memory. You should use:
void *new_ptr = realloc(ptr, new_size);
if (new_ptr == NULL)
…handle out of memory condition…ptr is still valid!
ptr = new_ptr;
You should also always check that memory allocations succeed. If they fail, you end up dereferencing a null pointer, which leads to crashes.

Related

does the pointer reallocate memory as it increments?

how can i stop *str from filling memory that i didnt give to it, without having to add an ending condition which in this case is : i <= n
do{
//instructions;
} while (... && i <= n);
in this exemple i reserved only 3 bytes of memory to *str but when i run my code and input more than 3 characters it still works... how does that happen shouldnt it give an error cuz there isnt enough memory for the rest of the characters ? what if the selected empty adresses were xxxxx1 xxxxx2 xxxxx3 and then xxxxx4 is full will it stop and output only the 3 characters without an error ?
P.s : I am aware of the function gets() but i dont want to use it because it reallocates memory. i thought that by entering character by character i will solve the problem and stop the user from filling the pointer because this time there is no memory reallocation and *str only has 3 blocks of memory so the rest will go to the buffer and *str will stop at *(str + 2)
hope u understood the problem and thank u for answering
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main()
{
int i = -1, n = 3;
char *str = (char *)malloc(n*sizeof(char));
printf("Enter a string: ");
do
{
i++;
str[i] = getchar();
} while (str[i] != '\n' && i < n);
str[i] = '\0';
printf("Entered string is: %s", str);
return 0;
}
C doesn't perform any type of bounds checking on arrays or allocated memory. That's part of what makes it fast.
That also means that reading or writing past the end of an array causes undefined behavior which basically means there's no guarantee what the program will do. The language trusts you to do the proper thing, so it's up to you to ensure that you don't do something you shouldn't.
Also, gets doesn't reallocate memory. In fact, it shouldn't be used at all specifically because it doesn't perform any bounds checking.
Your example doesn't work if the input string is longer than two characters since it then tries to write beyond the array. What will happen when you try to write outside of the array is undefined, which means that it may work by pure chance under some circumstances. Try this safe function instead which always reads the entire line and truncates the result if necessary:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void ReadLine(char result[], int resultLen)
{
int ch, i;
assert(resultLen > 0);
i = 0;
ch = getchar();
while ((ch != '\n') && (ch != EOF)) {
if (i < resultLen - 1) {
result[i] = ch;
i++;
}
ch = getchar();
}
result[i] = '\0';
}
int main(void)
{
int n = 3;
char *str = malloc(n);
printf("Enter a string: ");
ReadLine(str, n);
printf("Entered string is: %s\n", str);
free(str);
return 0;
}

Replacing `goto` with a different programming construct

I m trying to do this little programm with defensive programming but its more than difficult for me to handle this avoiding the Loop-Goto as i know that as BAD programming. I had try with while and do...while loop but in one case i dont have problem. Problem begins when i m going to make another do...while for the second case ("Not insert space or click enter button"). I tried and nested do...while but here the results was more complicated.
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i;
int length;
char giventext [25];
Loop:
printf("String must have 25 chars lenght:\n");
gets(giventext);
length = strlen(giventext);
if (length > 25) {
printf("\nString has over %d chars.\nMust give a shorter string\n", length);
goto Loop;
}
/* Here i trying to not give space or nothing*/
if (length < 1) {
printf("You dont give anything as a string.\n");
goto Loop;
} else {
printf("Your string has %d\n",length);
printf("Letter in lower case are: \n");
for (i = 0; i < length; i++) {
if (islower(giventext[i])) {
printf("%c",giventext[i]);
}
}
}
return 0;
}
Note that your code is not defensive at all. You have no way to avoid a buffer overflow because,
you check for the length of the string after it has been input to your program so after the buffer overflow has already occurred and
you used gets() which doesn't check input length and thus is very prone to buffer overflow.
Use fgets() instead and just discard extra characters.
I think you need to understand that strlen() doesn't count the number of characters of input but instead the number of characters in a string.
If you want to ensure that there are less than N characters inserted then
int
readinput(char *const buffer, int maxlen)
{
int count;
int next;
fputc('>', stdout);
fputc(' ', stdout);
count = 0;
while ((next = fgetc(stdin)) && (next != EOF) && (next != '\n')) {
// We need space for the terminating '\0';
if (count == maxlen - 1) {
// Discard extra characters before returning
// read until EOF or '\n' is found
while ((next = fgetc(stdin)) && (next != EOF) && (next != '\n'))
;
return -1;
}
buffer[count++] = next;
}
buffer[count] = '\0';
return count;
}
int
main(void)
{
char string[8];
int result;
while ((result = readinput(string, (int) sizeof(string))) == -1) {
fprintf(stderr, "you cannot input more than `%d' characters\n",
(int) sizeof(string) - 1);
}
fprintf(stdout, "accepted `%s' (%d)\n", string, result);
}
Note that by using a function, the flow control of this program is clear and simple. That's precisely why goto is discouraged, not because it's an evil thing but instead because it can be misused like you did.
Try using functions that label logical steps that your program needs to execute:
char * user_input() - returns an input from the user as a pointer to a char (using something other than get()! For example, look at scanf)
bool validate_input(char * str_input) - takes the user input from the above function and performs checks, such as validate the length is between 1 and 25 characters.
str_to_lower(char * str_input) - if validate_input() returns true you can then call this function and pass it the user input. The body of this function can then print the user input back to console in lower case. You could use the standard library function tolower() here to lower case each character.
The body of your main function will then be much simpler and perform a logical series of steps that tackle your problem. This is the essence of defensive programming - modularising your problem into separate steps that are self contained and easily testable.
A possible structure for the main function could be:
char * user_input();
bool validate_input(char *);
void str_to_lower(char *);
int main()
{
char * str_input = user_input();
//continue to get input from the user until it satisfies the requirements of 'validate_input()'
while(!validate_input(str_input)) {
str_input = user_input();
}
//user input now satisfied 'validate_input' so lower case and print it
str_to_lower(str_input);
return 0;
}

how to compare character against set of given characters in C?

I'd like to be able to compare a character on stdin with a characters of my specification. The purpose of this is to filter out every other input as wrong, while maintaining only the specified single chars as commands. Like on stdin "nn" or "qddaw" -> wrong go again but "n" make something useful.
Here is what I have in mind "code-wise":
if (input does not contain 'c' or 's' or 'q' or 'n') {
printf("some kind of error");
}
Well I tried to create an array with specified characters like array[] = {'a', 'b', 'c'} so I could be able to compare it with a string on the stdin with function strncmp.. like
char c[256];
scanf("%s", c)
if (strncmp(array, c, 1) != 0) printf("error");
but it doesn't seem to work. Any suggestions?
Edit1: Here is actual piece of code:
char c[256];
char* s = "nsrld";
char* quiter = "q";
do
{
printf(">");
scanf("%s", c);
if (only when there is no 'n' or 's' or other char from char* s on input)
{
errorHandle(ERROR_WRONG_CMD);
}
scanf("%*[^\n]"); scanf("%*c");
} while (strcmp(c,quiter) != 0);
as you can see I handled the 'q' thing quite well, but multiple chars are pain in the ass. Thanks for any advice.
Edit 2: or in other words I need a function which will compare input with a set of given characters and only if there is one OR another (like 'q' or 's' the function will pass (but not if there are characters together like 'qs')
I didn't make myself clear enough. What I need is input "type what ever you want" like "wwqwqe" and do the error unless the input is just 'c' or just 's' (and a few more).
char usersInput[200] = ""; /* A buffer to hold the input values */
char *result = gets(usersInput); /* Fill the buffer from stdin */
if (result != NULL) /* If we got something */
{
if (strlen(usersInput) == 1) /* the input must be exactly 1 character */
{
char ch = usersInput[0];
if (strchr(ch, "csqn") == NULL) /* It must be a valid values */
{
printf("Evil Bad Character <%c>\n", ch);
}
else
{
/* Do stuff with the known valid input value ch */
}
}
else
{
puts("The input value must be exactly 1 character\n");
puts("and must be 'c', 's', 'q' or 'n'");
}
}
else
{
puts("EOF or ERROR while reading stdin\n");
}
This should do the job.
One warning. gets is not smart enough to know that usersInput is 200 characters long.
It will gleefully let you type in 201 characters or more, which overwrites other characters in memory. That sort of thing can lead to hard-to-find bugs.
int ch = getchar();
if (ch != EOF)
{
if (strchr("csqn", ch) == NULL)
{
printf("Evil Bad Character <%c> in Hex %02X\n", ch, ch);
}
else
{
/* Do stuff with ch */
}
}
else
{
printf("EOF on input\n");
}
char c = getchar();
switch (c) {
case 'c':
case 's':
case 'q':
case 'n':
do_something();
break;
default:
print_error();
};
The above code should work. I don't know why your if statement wasn't working. Generally a switch works well in this type of scenario too.
Your first solution should work. If that's the exact same code you posted - then your problem might because the printf needs a newline at the end to flush to console.
I have thought the string as sets... So if the intersection of them is the void set then we will fail -> printf("Error")... otherwise the output is none...
#include <stdio.h>
#include <string.h>
int intersection(char* source, char* search)
{
int i,j;
for(i = 0; i < strlen(search); i++)
if(strchr(source,search[i]))j++;
if(j != strlen(search))return 0;
else return 1;
}
int main()
{
char *letters = "eo";
char *p = "hello";
int e = intersection(p,letters);
if(e==1)puts("Non Void");
else puts("Void");
}
While it looks as if you've got a solution, it might be worth mentioning that what you're asking for doesn't sound as if it's all that far away from the standard 'getopt' functionality... See http://www.gnu.org/software/libc/manual/html_node/Getopt.html for example.
This worked for me:
char c[256];
char* s = "nqsrld";
char* quiter = "q";
do
{
printf(">");
scanf("%s", c);
if ((strpbrk(s, c) == 0) || (strlen(c) >= 2))
{
errorHandle(ERROR_WRONG_CMD);
}
scanf("%*[^\n]"); scanf("%*c");
} while (strcmp(c,quiter) != 0);
Thanks to everyone for their help.
Write a function
int IsGood(int c)
{
if(c=='a'||c=='b'||c=='c')
return 1;
else
return 0;
}

read string of character and assign it to an array

I don't know how to work with scanf and get the input of it for the entry of the function readBigNum I want to make array until the user entered the Enter and also I want to write a function for assigning it into an array and return the size of the large number
I want readBigNum to exactly have the char *n but I can not relate it in my function
#include <stdio.h>
int readBigNum(char *n)
{
char msg[100],ch;
int i=0;
while((ch=getchar())!='\n')
{
if(ch!='0'||ch!='1'||ch!='2'||ch!='3'||ch!='4'||ch!='5'||ch!='6'||ch!='7'||ch!='8'||ch!='9')
return -1;
msg[i++]=ch;
}
msg[i]='\0';
i=0;
return i;
}
int main()
{
const char x;
const char n;
n=scanf("%d",x);
int h=readBigNum(&n);
printf(h);
}
If I understand your question correctly, you want to implement a function that will read numbers from stdin storing them in a buffer. If a non-number is encountered, you want to return -1. If a new-line is encountered, you want to return the number of characters that were read. If that's correct, you'll probably want your code to look something like the following:
#include <stdio.h>
int readBigNum(char* n)
{
char ch;
int i=0;
while ((ch = getchar()) != '\n') {
if (ch < '0' || ch > '9') {
return -1;
}
n[i++] = ch;
}
n[i] = '\0';
return i;
}
int main(void) {
char buf[100];
int bytes = readBigNum(buf);
printf("%s\n", buf);
printf("%d\n", bytes);
};
The main differences from your implementation
The array to be populated is initialized in main and passed to the readBigNum function. This is a little simpler than having the function control the memory, in which case you would need likely need to deal with malloc and free. Even with this, you run the risk of a buffer overrun and will likely want to take additional precautions to prevent that.
The function does not set i to 0 before returning it. The original code could never return a value other than -1 (on error) or 0, which didn't appear to be the intent.
This code doesn't use scanf. Given your description of what you wanted to accomplish, using scanf didn't appear to be a good fit, however if you provide more information on why you were calling it might help to inform this answer.
The printf call was incorrect, it has been updated to print the number of bytes returned, and an additional printf call was added to print the updated buffer.
Remember that getchar() returns type int, not char. This is because the function may return EOF (which is defined as a negative integer with no particular value).
Also, for functions that deal with buffers, it is always a good idea to take an extra argument that describes the size of the array. This helps reduce buffer overruns because you know how far you can go. With your existing function, if the user types more than 100 characters, your buffer is overrun.
#include <stdio.h>
#include <ctype.h>
int readBigNum(char *n, size_t len)
{
int ch;
int i = 0;
// we make sure 'i' is less than 'len - 1' to leave space for '\0'
while((ch = getchar()) != EOF && i < (len - 1))
{
if (ch == '\n') // stop on linefeed
break;
else if (!isdigit(ch))) // abort on invalid character
return -1;
else
n[i++] = (char) ch;
}
msg[i] = '\0';
return i;
}
int main(void)
{
char buf[100];
int result = readBigNum(buf, sizeof buf);
if (result > 0)
printf("Length %d : %s\n", result, buf);
else
printf("Invalid number!\n");
}

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