I have a hard time understanding how you process ascii files in c. I have no problem opening files and closing them or reading files with one value on each line. However, when the data is separated with characters, I really don't understand what the code is doing at a lower level.
Example: I have a file containing names separated with comas that looks like this:
"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER"
I have created an array to store them:
char names[6000][20];
And now, my code to process it is while (fscanf(data, "\"%s\",", names[index]) != EOF) { index++; }
The code executes for the 1st iteration and names[0] contains the whole file.
How can I separate all the names?
Here is the full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char names[6000][20]; // an array to store 6k names of max length 19
FILE * data = fopen("./022names.txt", "r");
int index = 0;
int nbNames;
while (fscanf(data, "\"%s\",", names[index]) != EOF) {
index++;
}
nbNames = index;
fclose(data);
printf("%d\n", index);
for (index=0; index<nbNames; index++) {
printf("%s \n", names[index]);
}
printf("\n");
return 0;
}
PS: I am thinking this might also be because of the data structure of my array.
If you want a simple solution, you can read the file character by character using fgetc. Since there are no newlines in the file, just ignore quotation marks and move to the next index when you find a comma.
char names[6000][20]; // an array to store 6k names of max length 19
FILE * data = fopen("./022names.txt", "r");
int name_count = 0, current_name_ind = 0;
int c;
while ((c = fgetc(data)) != EOF) {
if (c == ',') {
names[name_count][current_name_ind] = '\0';
current_name_ind = 0;
++name_count;
} else if (c != '"') {
names[name_count][current_name_ind] = c;
++current_name_ind;
}
}
names[name_count][current_name_ind] = '\0';
fclose(data);
"The code executes for the 1st iteration and names[0] contains the whole file...., How can I separate all the names?"
Regarding the first few statements:
char names[6000][20]; // an array to store 6k names of max length 19
FILE * data = fopen("./022names.txt", "r");
What if there are there are 6001 names. Or one of the names has more than 20 characters?
Or what if there are way less than 6000 names?
The point is that with some effort to enumerate the tasks you have listed, and some time mapping out what information is needed to create the code that matches your criteria, you can create a better product: The following is derived from your post:
Process ascii files in c
Read file content that is separated by characters
input is a comma separated file, with other delimiters as well
Choose a method best suited to parse a file of variable size
As mentioned in the comments under your question there are ways to create your algorithms in such way as to flexibly allow for extra long names, or for a variable number of names. This can be done using a few C standard functions commonly used in parsing files. ( Although fscanf() has it place, it is not the best option for parsing file contents into array elements.)
The following approach performs the following steps to accomplish the user needs enumerated above
Read file to determine number of, and longest element
Create array sized to contain exact contents of file using count of elements and longest element using variable length array (VLA)
Create function to parse file contents into array. (using this technique of passing VLA as function argument.)
Following is a complete example of how to implement each of these, while breaking the tasks into functions when appropriate...
Note, code below was tested using the following input file:
names.txt
"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER",
"Joseph","Bart","Daniel","Stephan","Karen","Beth","Marcia",
"Calmazzothoulumus"
.
//Prototypes
int count_names(const char *filename, size_t *count);
size_t filesize(const char *fn);
void populateNames(const char *fn, int longest, char arr[][longest]);
char *filename = ".\\names.txt";
int main(void)
{
size_t count = 0;
int longest = count_names(filename, &count);
char names[count][longest+1];//VLA - See linked info
// +1 is room for null termination
memset(names, 0, sizeof names);
populateNames(filename, longest+1, names);
return 0;
}
//populate VLA with names in file
void populateNames(const char *fn, int longest, char names[][longest])
{
char line[80] = {0};
char *delim = "\",\n ";
char *tok = NULL;
FILE * fp = fopen(fn, "r");
if(fp)
{
int i=0;
while(fgets(line, sizeof line, fp))
{
tok = strtok(line, delim);
while(tok)
{
strcpy(names[i], tok);
tok = strtok(NULL, delim);
i++;
}
}
fclose(fp);
}
}
//passes back count of tokens in file, and return longest token
int count_names(const char *filename, size_t *count)
{
int len=0, lenKeep = 0;
FILE *fp = fopen(filename, "r");
if(fp)
{
char *tok = NULL;
char *delim = "\",\n ";
int cnt = 0;
size_t fSize = filesize(filename);
char *buf = calloc(fSize, 1);
while(fgets(buf, fSize, fp)) //goes to newline for each get
{
tok = strtok(buf, delim);
while(tok)
{
cnt++;
len = strlen(tok);
if(lenKeep < len) lenKeep = len;
tok = strtok(NULL, delim);
}
}
*count = cnt;
fclose(fp);
free(buf);
}
return lenKeep;
}
//return file size in bytes (binary read)
size_t filesize(const char *fn)
{
size_t size = 0;
FILE*fp = fopen(fn, "rb");
if(fp)
{
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
fclose(fp);
}
return size;
}
You can use the in-built strtok() function which is easy to use.
I have used the tok+1 instead of tok to omit the first " and strlen(tok) - 2 to omit the last ".
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char names[6000][20]; // an array to store 6k names of max length 19
FILE * data = fopen("./022names.txt", "r");
int index = 0;
int nbNames;
char *str = (char*)malloc(120000*sizeof(char));
while (fscanf(data, "%s", str) != EOF) {
char *tok = strtok(str, ",");
while(tok != 0){
strncpy(names[index++], tok+1, strlen(tok)-2);
tok = strtok(0, ",");
}
}
nbNames = index;
fclose(data);
free(str); // just to free the memory occupied by the str variable in the heap.
printf("%d\n", index);
for (index=0; index<nbNames; index++) {
printf("%s \n", names[index]);
}
printf("\n");
return 0;
}
Also, the parameter 120000 is just the maximum number of characters that can be in the file. It is just 6000 * 20 as you mentioned.
Related
My program needs to print longest word which contains only letters from a file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int checkString(const char s[]) {
unsigned char c;
while ((c = *s) && (isalpha(c) || isblank(c)))
++s;
return *s == '\0';
}
int main() {
char file_name[]="document.txt";
FILE *fp = fopen(file_name, "r");
char *largest = str;
int largest_len = 0;
while (fgets(file_name, 1000, fp) != NULL) {
char *temp = strtok(file_name, " ");
while (temp != NULL) {
if (strlen(temp) > largest_len) {
strcpy(largest, temp);
largest_len = strlen(largest);
}
temp = strtok(NULL, "\",.,1,2,4,5,6,7,8,9 ");
}
}
if(checkString(largest))
printf("%s", largest);
fclose(fp);
return 0;
}
In my code, if the largest word contains only letters it will be printed. How to modify this code to check next words if the largest doesn't contain only letters?
First of all, you cannot store the pointer to longest word like that. You re-use str for the next line and so the pointer is not likely to point to something useful.
Second, while strtok() appears simple, initially, I tend to apply a straightforward approach to a straightforward problem.
The problem is O(n) (where n is the length of the document). You just need to go through it character by character. Of course, since every line is ended by a \n, you can use the line based approach in this case.
So, instead of strtok, simply check each character, if it is a legal word character (an alphanumeric character, that is). You can easily do so with the standard library function isalpha() from header ctype.h.
Below is the program, copying the longest string into a dedicated buffer, using isalpha() and doing the line based reading of the file, just like the code in the original question did.
Of course, this code assumes, no line is ever longer than 999 characters.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
static size_t gulp(const char* line, size_t istart, size_t len) {
size_t n = 0;
for (size_t i = istart; i < len; i++, n++) {
if (!isalpha(line[i])) {
break;
}
}
return n;
}
int main(int argc, const char * argv[]) {
FILE* f = fopen("document.txt","r");
char line[1000];
char longest_word[1000];
size_t longest_word_length = 0;
while (fgets(line, sizeof(line), f) != NULL) {
size_t i0 = 0;
size_t line_length = strlen(line);
while (i0 < line_length) {
if (isalpha(line[i0])) {
size_t n = gulp(line, i0, line_length);
if (n > longest_word_length) {
strncpy(longest_word, &line[i0], n);
longest_word[n] = '\0';
longest_word_length = n;
}
i0 = i0 + n;
} else {
i0++;
}
}
}
fclose(f);
f = NULL;
if (longest_word_length > 0) {
printf("longest word: %s (%lu characters)\n",
longest_word, longest_word_length);
}
return 0;
}
There are a number of problems here:
you use the same buffer (str) for two different uses: as a read buffer and to store the longest word. If you find the largest word in the first line, the word will be erased when reading the second line. Furthemore, if you find a rather long word at the beginning of a line, the strings pointed to by largest and temp could overlap which leads to undefined behaviour => use a different array or strdup (and free) for largest
you only use the space as possible separator. You should wonder whether you should add tab and/or punctuations
once you have got a word you should ensure that it only contains valid letters before testing its length and ignore it if for example it contains digits.
if a single line can be longer than 1000 characters, you should wrap the end of the current part before the beginning of the next one for the possible case where a long word would be splitted there.
For additional corner case processing, you should specify what to do if a word contains illegal characters but only at one side. For example if . is not used as a word delimiter, a word with an embedded . like "a.b" should be ignored, but a terminating . should only be stripped (like "example." should become "example"
I think the order you do things should be a bit different, here is an example
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int isCandidate(char* word);
int main(int argc, char* argv[])
{
if (--argc == 0)
{
perror("not enough command line arguments, expecting a filename");
return -1;
}
++argv;
FILE* fp = fopen(*argv, "r");
if (fp == NULL)
{
perror(*argv);
return -1;
}
// get size of file
fseek(fp, 0L, SEEK_END);
long fileLength = ftell(fp);
if (fileLength < 1)
{
perror("file is empty");
return -1;
}
fseek(fp, 0L, SEEK_SET); // position file pointer at the beginning again
// allocate space for the whole file and then read it in
// for a text file it should be OK to do so since they
// normally are not that large.
char* buffer = malloc(fileLength+1);
if (fread(buffer, 1, fileLength, fp) != 0)
{
buffer[fileLength] = '\0'; // make sure the buffer ends with \0
}
else
{
perror("Failed reading into buffer");
return -1;
}
fclose(fp); // we are done with the file
const char filter[] = " \n\r";
char* longestWord = malloc(fileLength+1); // max length in theory
long unsigned int maxLength = 0;
for (char* token = strtok(buffer, filter); token != NULL; token = strtok(NULL, filter))
{
if (isCandidate(token))
{
if (strlen(token) > maxLength)
{
strcpy(longestWord, token);
maxLength = strlen(token);
}
}
}
printf("Longest word:'%s', len=%lu\n", longestWord, maxLength);
free(longestWord);
free(buffer);
}
int isCandidate(char* word)
{
if (word == NULL)
{
perror("invalid argument to isCandidate");
return 0;
}
for (char* ch = word; *ch; ++ch)
{
if (!isalpha(*ch)) return 0;
}
return 1;
}
I am new to C and am getting very frustrated with learning this language. Currently I'm trying to write a program that reads in a program textfile, reads and prints all the string literals, and tokens each on separate line. I have most of it except for one snag. within the text file there is a line such as: (..text..). I need to be able to search, read and print all the text is inside the parentheses on it's own line. Here is an idea I have so far:
#define KEY 32
#define BUFFER_SIZE 500
FILE *fp, *fp2;
int main()
{
char ch, buffer[BUFFER_SIZE], operators[] = "+-*%=", separators[] = "(){}[]<>,";
char *pus;
char source[200 + 1];
int i, j = 0, k = 0;
char *words = NULL, *word = NULL, c;
fp = fopen("main.txt", "r");
fp2 = fopen ("mynewfile.txt","w") ;
while ((ch = fgetc(fp)) != EOF)
{
// pus[k++] = ch;
if( ch == '(')
{
for ( k = 0;, k < 20, K++){
buffer[k] = ch;
buffer[k] = '\0';
}
printf("%s\n", buffer)
}
....
The textfile is this:
#include <stdio.h>
int main(int argc, char **argv)
{
for (int i = 0; i < argc; ++i)
{
printf("argv[%d]: %s\n", i, argv[i]);
}
}
So far I've been able to read char by char and place it into a buffer. But this idea just isn't working, and I'm stumped. I've tried dabbling with strcopy(), ands strtok, but they all take char arrays. Any ideas would be appreciated thank you.
Most likely the best way would be to use fgets() with a file to read in each line as a string (char array) and then delimit that string. See the short example below:
char buffer[BUFFER_SIZE];
int current_line = 0;
//Continually read in lines until nothing is left...
while(fgets(buffer, BUFFER_SIZE - 1, fp) != NULL)
{
//Line from file is now in buffer. We can delimit it.
char copy[BUFFER_SIZE];
//Copy as strtok will overwrite a string.
strcpy(copy, buffer);
printf("Line: %d - %s", current_line, buffer); //Print the line.
char * found = strtok(copy, separators); //Will delmit based on the separators.
while(found != NULL)
{
printf("%s", found);
found = strtok(NULL, separators);
}
current_line++;
}
strtok will return a char pointer to where the first occurrence of a delimiter is. It will replace the delimiter with the null terminator, thereby making "new" string. We can pass NULL to strtok to tell it to continue where it left off. Using this, we can parse line by line from a file based on multiple delimiters. You could save these individual string or evaluate them further.
for (int i = 0; i < 4; i++) {
for (int j = 0; j <4; i++) {
while (c != EOF)
token = strtok((fgets(token,5,fp)), delim);
}
}
Hey everyone, I'm new to C and I was given a project to take a csv file and count the average number of the values in each column. Right now I'm trying to parse the lines by the commas. I found the function [strtok], but I'm definitely implementing it incorrectly. I have the number of rows and columns in the csv file, I just need help figuring out how to parse each line by "," and place those values into a 2D array. Above is my current code that I was going to use to append the values to the array, but I keep getting a "Segmentation fault". Any help would be appreciated.
Here is the whole code for the function. I include stdio.h and stdlib.h:
void main() {
char *strcat(char *dest, const char *src);
char *strtok(char *str, const char *delim);
char *file_name = "test.txt";
FILE *fp = fopen(file_name, "r");
int array[4][4];
//int array1 [2] = {1, 3};
int counter = 0;
char *token = " ";
const char *delim = (const char *)',';
char c = fgetc(fp);
for (int i = 0; i < 4; i++) {
token = "";
for (int j = 0; j <4; i++) {
while (c != EOF)
token = strtok((fgets(token,5,fp)), delim);
}
}
fclose(fp);
}
A sample input would be something like this:
10,20,30,60
40,50,60,70
70,80,90,80
100,110,120,70
Yes you are right, you are using strtok incorrectly.
The first thing I would do is to read each line and the parse the line using
strtok, like this:
char line[1024];
const char *delim=",\n";
while(fgets(line, sizeof line, fp))
{
char *token = strtok(line, delim);
do {
printf("token: %s\n", token);
} while(token = strtok(NULL, delim));
}
strtok requires that all subsequent calls of strtok must be called with
NULL. strtok will return NULL when no more token can be found, usually the
end of the line has been reached. Note that I added the newline in the
delimiters argument. When the destination buffer is large enough fgets writes
the newline as well. Putting the newline in the delimiters list is nice trick
because strtok will get rid of the newline for you.
The code above gives you a way getting each cell of the csv, as a string. You
would have to convert the values yourself. This is the tricky bit, if the csv
contains empty spaces, quotes, etc, you need different strategies to parse the
correct value of the cell. You can use function like strtol & friend which
allow you to recover from errors, but they are not bullet proof, there will be
cases when they fail as well.
An easy example would be:
char line[1024];
const char *delim=",\n";
while(fgets(line, sizeof line, fp))
{
char *token = strtok(line, delim);
do {
int val;
if(sscanf(token, "%d", &n) != 1)
fprintf(stderr, "'%s' is not a number!\n", token);
else
printf("number found: %d\n", val);
} while(token = strtok(NULL, delim));
}
Note that this not cover all cases, for example cell that are in quotes.
The last thing to be done would be to store the values. One way of doing it is
to allocate memory for a pointer to an int array and reallocate memory for
every cell. Here again the problem lies in the csv file, sometimes they have the
wrong format, some rows will be empty or some rows will have more or less
columns than the other rows, this can be tricky. At this point it would be a good
idea to use a library for parsing csv.
The following code will assume that csv is well formatted and the number of
columns is always the same across all rows and no line is longer than 1023
characters long. When *cols is 0, I calculate the number of columns base on
the first line. If other rows have less columns, all remaining values will be 0
(because of the calloc sets new allocated memory to 0). If there are more
colmuns than in the first row, this columns will be ignored:
int **parse_csv(const char *filename, size_t *rows, size_t *cols)
{
if(filename == NULL || rows == NULL || cols == NULL)
return NULL;
FILE *fp = fopen(filename, "r");
if(fp == NULL)
return NULL;
int **csv = NULL, **tmp;
*rows = 0;
*cols = 0;
char line[1024];
char *token;
char *delim = ",\n";
while(fgets(line, sizeof line, fp))
{
tmp = realloc(csv, (*rows + 1) * sizeof *csv);
if(tmp == NULL)
return csv; // return all parsed rows so far
csv = tmp;
if(*cols == 0)
{
// calculating number of rows
char copy[1024];
strcpy(copy, line);
token = strtok(copy, delim);
do {
(*cols)++;
} while((token = strtok(NULL, delim)));
}
int *row = calloc(*cols, sizeof *row);
if(row == NULL)
{
if(*rows == 0)
{
free(csv);
return NULL;
}
return csv; // return all parsed rows so far
}
// increment rows count
(*rows)++;
size_t idx = 0;
token = strtok(line, delim);
do {
if(sscanf(token, "%d", row + idx) != 1)
row[idx] = 0; // in case the conversion fails,
// just to make sure to have a defined value
// in the cell
idx++;
} while((token = strtok(NULL, delim)) && idx < *cols);
csv[*rows - 1] = row;
}
fclose(fp);
return csv;
}
void free_csv(int **csv, size_t rows)
{
if(csv == NULL)
return;
for(size_t i = 0; i < rows; ++i)
free(csv[i]);
free(csv);
}
Now you can parse it like this:
size_t cols, rows;
int **csv = parse_csv("file.csv", &rows, &cols);
if(csv == NULL)
{
// error handling...
// do not continue
}
...
free_csv(csv, rows);
Now csv[3][4] would give you the cell at row 3, col 4 (starting from 0).
edit
Things I noticed from you code:
void main() is wrong. main should have only one of the following prototypes:
int main(void);
int main(int argc, char **argv);
int main(int argc, char *argv[]);
Another:
int main(void)
{
char *strcat(char *dest, const char *src);
char *strtok(char *str, const char *delim);
...
}
Don't put that in the main function, put it outside, also there are standard
header files for this. In this case include string.h
#include <string.h>
int main(void)
{
...
}
Another
const char *delim = (const char *)',';
This is just wrong, it's like trying to sell an apple and call it orange. ','
is a single character of type char. It has the value 44. It's the same as
doing:
const char *delim = (const char*) 44;
you are setting the address where delim should point to 44.
You have to use double quotes:
const char *delim = ",";
Note that 'x' and "x" are not the same. 'x' is 120 (see ASCII), it's
a single char. "x" is a string literal, it returns you a pointer to the start
of a sequence of characters that ends with the '\0'-terminating byte, aka a
string. Those are fundamentally different things in C.
How do i get the position of delimited separated string?
My text file looks like
at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash
avahi:x:109:111:User for Avahi:/var/run/avahi-daemon:/bin/false
beagleindex:x:110:112:User for Beagle indexing:/var/cache/beagle:/bin/bash
My C code looks like
#include<stdio.h>
int main(int argc, char *argv[])
{
char *str, *saveptr;
char ch[100];
char *sp;
FILE *f;
int j;
char searchString[20];
char *pos;
f = fopen("passwd", "r");
if (f == NULL)
{
printf("Error while opening the file");
}
while (fgets(ch, sizeof ch, f)!= NULL)
{
/*printf("%s\n", ch); */
for (j = 1, str = ch; ; j++, str= NULL)
{
char *token = strtok_r(str, ": ", &saveptr);
if (token == NULL)
break;
//printf("%s---\n---", token);
printf("%s",token);
}
}
fclose(f);
well, using strtok(str, ": ", will split your string on spaces as well as colons, which is probably not what you want. In addition, strtok treats multiple consecutive delimiter characters as a single delimiter (so it will never return an empty string between two colons), which is not what you want for parsing passwd.
Instead, you probably just want to use strchr:
while (fgets(ch, sizeof ch, f)!= NULL) {
char *token, *end;
for (j = 1, token = ch; token; j++, token = end) {
if ((end = strchr(token, ':'))) *end++ = 0;
...do something with token and j
I do not think you have to use strtok() just to get the position of a token separated by delimiters, rather simply walk through each line, and do a char by char comparison for the delimiter... (hope this will help you)
I prepared an input file called GetDelimPosition.txt:
at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash
avahi:x:109:111:User for Avahi:/var/run/avahi-daemon:/bin/false
jamil:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash
javier:x:109:111:User for Avahi:/var/run/avahi-daemon:/bin/false
jiame:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash
jose:x:109:111:User for Avahi:/var/run/avahi-daemon:/bin/false
And used the following code: (of course you will modify as needed)
#include <ansi_c.h>
//edit this line as needed:
#define FILE_LOC "C:\\dev\\play\\GetDelimPosition.txt"
int main(void)
{
FILE * fp;
char ch[260];
int line=-1;
int position[80][100]={0}; //lines x DelimPosition
memset(position, 0, 80*100*sizeof(int));
int i=-1,j=0, k=0;
int len;
fp = fopen(FILE_LOC, "r");
while (fgets(ch, sizeof ch, fp)!= NULL)
{
line++; //increment line
len = strlen(ch);
for(j=0;j<len;j++)
{
if(ch[j] == ':')
{
position[line][k] = j+1;//position of token (1 after delim)
k++; //increment position index for next token
}
}
k=0; //getting new line, zero position index
}
fclose(fp);
return 0;
}
To get the following results: (rows are lines in file, columns are positions of each token. First token is assumed at position 0, and not reported)
I'm trying to store different values that are taken from a file line by line. The lines in the text file read as something shown below
100000,player1,long title name
300000,someotherplayer,another long title name
45512845,thisplayer,one more long title name
I want to store each value that is comma separated into three different arrays, (int)number, (str)player_name, (str)title_name.
I have some code below, but it doesn't compile.
ptr_file=fopen("text.txt", "r");
char buffer[1000];
int line;
line = 0;
while(fgets(buffer, sizeof(buffer), ptr_file) != NULL){
char number[line]=strtok(buffer, ",");
char player_name[line]=strtok(NULL, ",");
char title_name[line]=strtrok(NULL, ",");
}
Can someone give me some advice on this?
So, there are a couple of issues with your code,
You open the file in mode "o" which I'm not really sure what it is, I suspect you want "r"
strtok returns a char * which you cannot assign to a char[].
One the second run through the loop you will overwrite the data in buffer.
I would do something like this:
struct player {
int number;
char player_name[64];
char title_name[256];
};
int main(void) {
FILE *ptrfile=fopen("text.txt", "r");
char buffer[1000];
int line;
struct player players[16];
line = 0;
if(ptrfile==NULL) return 0;
while(fgets(buffer, sizeof(buffer), ptrfile) != NULL){
if(strcmp(buffer, "") == 0) return 0;
char *number=strtok(buffer, ",");
char *player_name=strtok(NULL, ",");
char *title_name=strtok(NULL, ",");
players[line].number=atoi(number);
strcpy(players[line].player_name, player_name);
strcpy(players[line].title_name, title_name);;
line++;
}
fclose(ptrfile);
return 0
}
function strtok return a pointer, so it should be
char* p = strtok(...)
Check the reference here
This is something I did that was similar to what you seem to be doing. The problem you will find is that you want to make each value into a char* but you have to malloc each one then you can connect this char* into the array. It would also just be easier to do that with the numbers to then turn them into int later on.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *msg[100];
char temp[100];
int length, i;
int num = 0;
while((scanf("%s", &temp[0]) != EOF))
{
length = strlen(temp);
msg[num] = malloc((length+1 )* sizeof(char));
strcpy(msg[num], temp);
num++;
}
printf("There are %d words in the this input.\n", num);
for(i = 0; i < num; i++)
{
printf("%s\n", msg[i]);
}
return 0;
}
The thing with the malloc is that you will have to have each one unique because the words are all different sizes. I know this example isn't exactly what your doing but it will get you in the right direction.