I am supposed to write a program to extract Web addresses starting with www. and ending with .edu. The program displays Web address contained in the input entered by the user. If the input does not contain a web address that starts with www. and ends with .edu, the program should display a message that indicates such a web address cannot be found.
Input: http://www.usf.edu/admission
Output: www.usf.edu
Input: https://www.facebook.com/
Output: Web address starting with www. and ending with .edu not found
However when my program runs, it is not displaying the correct output. I don't have any compiler errors or warnings so I'm not sure where the issue could be.
// This program extracts the text from the website URL
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define STR_LEN 1000
void read_line(char *str, int n);
void pass_check(char *str);
void extract(char *s1, char *s2);
int main(void)
{
char instr[STR_LEN + 1];
char outstr[STR_LEN + 1];
printf("Please enter a URL: ");
read_line(instr, STR_LEN);
extract(instr, outstr);
puts(outstr);
pass_check(outstr);
return 0;
}
void extract(char *s1, char *s2) {
char *p, *q;
q = s2;
for (p = s1 + 7; *p != 0; p++) {
if (*p == '/')
break;
else {
*q = *p;
q++;
}
}
*q = '\0';
*p = '\0';
}
void read_line(char *str, int n) {
int ch;
int i = 0;
while ((ch = getchar()) != '\n') {
if (i < n) {
*str++ = ch;
i++;
}
}
*str = '\0';
}
void pass_check(char *str) {
const char *fref = "www";
const char *lref = "edu";
int len = strlen(str);
printf("%d", len);
char *l = &str[len - 3];
char f[STR_LEN + 1];
strncpy(f, str, 3);
if ((strcmp(f, fref) == 0) && strcmp(l, lref) == 0) {
printf("Output: ");
puts(str);
printf("\n");
} else
printf("Please only insert a .edu URL.");
}
The function strncpy() does not do what you think it does: strncpy(f, str, 3); will not append a null byte to f, so strcmp(f, fref); will actually have undefined behavior as f is uninitialized beyond the first 3 bytes.
Do not use this function, learn why from these blogs:
https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/
https://blog.liw.fi/posts/strncpy/
Also note that your readline() function will run an infinite loop is the file is empty or not terminated by a newline.
Here is a corrected version:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define STR_LEN 1000
void read_line(char *str, size_t n);
int extract(const char *str, char *dest);
int main(void) {
char instr[STR_LEN + 1];
char outstr[STR_LEN + 1];
printf("Please enter a URL: ");
read_line(instr, sizeof(instr));
if (extract(instr, outstr)) {
puts(outstr);
} else {
printf("Web address starting with www. and ending with .edu not found\n");
}
return 0;
}
int read_line(char *str, size size) {
int ch;
size_t i = 0;
while ((ch = getchar()) != EOF && c != '\n') {
if (i + 1 < size) {
str[i++] = ch;
}
}
str[i] = '\0';
return (ch == EOF && i == 0) ? EOF : i;
}
int extact(const char *str, char *dest) {
const char *p;
*dest = '\0';
for (;;) {
if ((p = strstr(str, "https://www.")) != NULL) {
p += 8; // skip the https:// prefix
} else
if ((p = strstr(str, "http://www.")) != NULL) {
p += 7; // skip the http:// prefix
} else {
break;
}
// URL starts with www.
size_t len = strcspn(p, "/ \n"); // compute length of website name
if (len > 8 && !memcmp(p + len - 4, ".edu", 4)) {
// copy website name, assuming dest is at least as large as str
strncat(dest, p, len);
return 1;
}
str = p + len;
}
return 0;
}
Related
I am in the stage of preparing myself for exams, and the thing that I m least proud of are my skills with strings. What I need to do is remove a word from a sentence, without using <string.h> library at all.
This is what I've got so far. It keeps showing me that certain variables are not declared, such as start and end.
#include <stdio.h>
/* Side function to count the number of letters of the word we wish to remove */
int count(char *s) {
int counter = 0;
while (*s++) {
counter++;
s--;
return counter;
}
/* Function to remove a word from a sentence */
char *remove_word(const char *s1, const char *s2) {
int counter2 = 0;
/* We must remember where the string started */
const char *toReturn = s1;
/* Trigger for removing the word */
int found = 1;
/* First we need to find the word we wish to remove [Don't want to
use string.h library for anything associated with the task */
while (*s1 != '\0') {
const char *p = s1;
const char *q = s2;
if (*p == *q)
const char *start = p;
while (*p++ == *q++) {
counter2++;
if (*q != '\0' && counter2 < count(s2))
found = 0;
else {
const char *end = q;
}
}
/* Rewriting the end of a sentence to the beginning of the found word */
if (found) {
while (*start++ = *end++)
;
}
s1++;
}
return toReturn;
}
void insert(char niz[], int size) {
char character = getchar();
if (character == '\n')
character = getchar();
int i = 0;
while (i < size - 1 && character != '\n') {
array[i] = character;
i++;
character = getchar();
}
array[i] = '\0';
}
int main() {
char stringFirst[100];
char stringSecond[20];
printf("Type your text here: [NOT MORE THAN 100 CHARACTERS]\n");
insert(stringFirst, 100);
printf("\nInsert the word you wish to remove from your text.");
insert(stringSecond, 20);
printf("\nAfter removing the word, the text looks like this now: %s", stringFirst);
return 0;
}
your code is badly formed, i strongly suggest compiling with:
gcc -ansi -Wall -pedantic -Werror -D_DEBUG -g (or similar)
start with declaring your variables at the beginning of the function block, they are known only inside the block they are declared in.
your count function is buggy, missing a closing '}' (it doesn't compile)
should be something like
size_t Strlen(const char *s)
{
size_t size = 0;
for (; *s != '\n'; ++s, ++size)
{}
return size;
}
implementing memmove is much more efficient then copy char by char
I reformatted you code for small indentation problems and indeed indentation problems indicate real issues:
There is a missing } in count. It should read:
/* Side function to count the number of letters of the word we wish to remove */
int count(char *s) {
int counter = 0;
while (*s++) {
counter++;
}
return counter;
}
or better:
/* Side function to count the number of letters of the word we wish to remove */
int count(const char *s) {
const char *s0 = s;
while (*s++) {
continue;
}
return s - s0;
}
This function counts the number of bytes in the string, an almost exact clone of strlen except for the return type int instead of size_t. Note also that you do not actually use nor need this function.
Your function insert does not handle EOF gracefully and refuses an empty line. Why not read a line with fgets() and strip the newline manually:
char *input(char buf[], size_t size) {
size_t i;
if (!fgets(buf, size, stdin))
return NULL;
for (i = 0; buf[i]; i++) {
if (buf[i] == '\n') {
buf[i] = '\0';
break;
}
}
return buf;
}
In function remove_word, you should define start and end with a larger scope, typically the outer while loop's body. Furthermore s1 should have type char *, not const char *, as the phrase will be modified in place.
You should only increment p and q if the test succeeds and you should check that p and q are not both at the end of their strings.
last but not least: you do not call remove_word in the main function.
The complete code can be simplified into this:
#include <stdio.h>
/* Function to remove a word from a sentence */
char *remove_word(char *s1, const char *s2) {
if (*s2 != '\0') {
char *dst, *src, *p;
const char *q;
dst = src = s1;
while (*src != '\0') {
for (p = src, q = s2; *q != '\0' && *p == *q; p++, q++)
continue;
if (*q == '\0') {
src = p; /* the word was found, skip it */
} else {
*dst++ = *src++; /* otherwise, copy this character */
}
}
*dst = '\0'; /* put the null terminator if the string was shortened */
}
return s1;
}
char *input(char buf[], size_t size) {
size_t i;
if (!fgets(buf, size, stdin))
return NULL;
for (i = 0; buf[i]; i++) {
if (buf[i] == '\n') {
buf[i] = '\0';
break;
}
}
return buf;
}
int main() {
char stringFirst[102];
char stringSecond[22];
printf("Type your text here, up to 100 characters:\n");
if (!input(stringFirst, sizeof stringFirst))
return 1;
printf("\nInsert the word you wish to remove from your text: ");
if (!input(stringSecond, sizeof stringSecond))
return 1;
printf("\nAfter removing the word, the text looks like this now: %s\n",
remove_word(stringFirst, stringSecond));
return 0;
}
Your start and end pointers are defined within a block which makes their scope limited within that block. So, they are not visible to other parts of your code, and if you attempt to reference them outside their scope, the compiler will complain and throw an error. You should declare them at the beginning of the function block.
That said, consider the following approach to delete a word from a string:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int delete_word(char *buf,
const char *word);
int main(void)
{
const char word_to_delete[] = "boy";
fputs("Enter string: ", stdout);
char buf[256];
fgets(buf, sizeof(buf), stdin);
if (delete_word(buf, word_to_delete))
{
printf("Word %s deleted from buf: ", word_to_delete);
puts(buf);
}
else
{
printf("Word %s not found in buf: ", word_to_delete);
puts(buf);
}
system("PAUSE");
return 0;
}
int chDelimit(int ch)
{
return
(ch == '\n' || ch == '\t') ||
(ch >= ' ' && ch <= '/') ||
(ch >= ':' && ch <= '#') ||
(ch >= '[' && ch <= '`') ||
(ch >= '{' && ch <= '~') ||
(ch == '\0');
}
char *find_pattern(char *buf,
const char *pattern)
{
size_t n = 0;
while (*buf)
{
while (buf[n] && pattern[n])
{
if (buf[n] != pattern[n])
{
break;
}
n++;
}
if (!pattern[n])
{
return buf;
}
else if (!*buf)
{
return NULL;
}
n = 0;
buf++;
}
return NULL;
}
char *find_word(char *buf,
const char *word)
{
char *ptr;
size_t wlen;
wlen = strlen(word);
ptr = find_pattern(buf, word);
if (!ptr)
{
return NULL;
}
else if (ptr == buf)
{
if (chDelimit(buf[wlen]))
{
return ptr;
}
}
else
{
if (chDelimit(ptr[-1]) &&
chDelimit(ptr[wlen]))
{
return ptr;
}
}
ptr += wlen;
ptr = find_pattern(ptr, word);
while (ptr)
{
if (chDelimit(ptr[-1]) &&
chDelimit(ptr[wlen]))
{
return ptr;
}
ptr += wlen;
ptr = find_pattern(ptr, word);
}
return NULL;
}
int delete_word(char *buf,
const char *word)
{
size_t n;
size_t wlen;
char *tmp;
char *ptr;
wlen = strlen(word);
ptr = find_word(buf, word);
if (!ptr)
{
return 0;
}
else
{
n = ptr - buf;
tmp = ptr + wlen;
}
ptr = find_word(tmp, word);
while (ptr)
{
while (tmp < ptr)
{
buf[n++] = *tmp++;
}
tmp = ptr + wlen;
ptr = find_word(tmp, word);
}
strcpy(buf + n, tmp);
return 1;
}
If you have to do it manually, just loop over the indicies of your string to find the first one that matches and than you’ll have a second loop that loops for all the others that matches and resets all and jumps to the next index of the first loop if not matched something in order to continue the searching. If I recall accuretaly, all strings in C are accesible just like arrays, you’ll have to figure it out how. Don’t afraid, those principles are easy! C is an easy langugae, thiught very long to write.
In order to remove: store the first part in an array, store the second part in an array, alloc a new space for both of them and concatinate them there.
Thanks, hit the upvote button.
Vitali
EDIT: use \0 to terminate your newly created string.
Suppose my string is: haha "lol"
I want to extract only lol
#include<stdio.h>
int main() {
char a[20]={0};
char *s="haha \"lol\"";
if(sscanf(s,"%*[^\"]'%[^\"]\"",a)==1){
printf("Found stuff inside quotes");
}
}
By applying a proper parser for the source language that you are parsing.
One-liners for parsing input are often fragile and hard get right.
That said, you can try with something like
const char *input = "haha \"lol\"";
char quoted[32];
if(sscanf(input, "%*[^\"]\"%31[^\"]\"", quoted) == 1)
{
printf("got '%s'\n", quoted);
}
This should be hardened but is enough to get you started.
Sometimes a little code goes a long way. All that is need is 2 calls to strchr()
extract_quoted_string() changed to pseudo-code.
const char *extract_quoted_string(const char *s, size_t *sz) {
const char *left = look_for_quote_start_at_s;
if (failure?) {
return NULL;
}
Update_left_to_the_next_possible_position
const char *right = look_for_quote_start_at_updated_left;
if (failure?) {
return NULL;
}
Compute_and_save_size_based_on_left_and_right
return left;
}
Test harness
void test(const char *s) {
printf("<%s> --> ", s);
size_t sz;
const char *extract = extract_quoted_string(s, &sz);
if (extract) {
printf("<%.*s>\n", (int) sz, extract);
} else {
printf("None\n");
}
}
int main() {
test("");
test("123");
test("\"123");
test("123\"");
test("\"123\"");
test("abc\"123");
test("abc\"123\"");
test("123\"xyz");
test("\"123\"xyz");
test("abc\"123\"xyz");
}
Expected output
<> --> None
<123> --> None
<"123> --> None
<123"> --> None
<"123"> --> <123>
<abc"123> --> None
<abc"123"> --> <123>
<123"xyz> --> None
<"123"xyz> --> <123>
<abc"123"xyz> --> <123>
I think that it is enough in the answer by unwind (even if you add code according to requirements)
A question similar to this question already exists.
Split unquoted string in C
When using that approach you can write follows:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ESCAPE '\\' //ESCAPE CHARACTER
typedef struct token {
const char *top;
const char *end;//point to next character
} Token;
Token getToken(const char **sp, char sep){
const char *s = *sp;
const char *top, *end;
Token token = { NULL, NULL};
while(*s && *s == sep)//skip top separators
++s;
if(!*s){
*sp = s;
return token;
}
token.top = s;
while(*s && *s != sep){
if(*s == ESCAPE)
++s;
else if(*s == '"'){
char *p = strchr(s + 1, '"');//search end '"'
while(p && p[-1] == ESCAPE)
p = strchr(p + 1, '"');
if(p)
s = p;
}
++s;
}
token.end = s;
*sp = s;
return token;
}
char *remove_escape(char *s){
char *from, *to;
from = to = s;
while(*from){
if(*from != ESCAPE)
*to++ = *from;
++from;
}
*to = 0;
return s;
}
char *ft_strsub(Token token){
size_t len = token.end - token.top;
char *sub = malloc(len + 1);//check return value
if (sub){
memcpy(sub, token.top, len);
sub[len] = 0;
}
return sub;
}
int main(int argc, char **argv){
char *str = NULL;
const char *s="haha \"lol\"";
Token token = getToken(&s, ' ');
while(token.top != NULL){
str = ft_strsub(token);
remove_escape(str);
if(*str == '"')//find it!
break;
free(str);
token = getToken(&s, ' ');
}
if(str){
printf("Found stuff inside quotes: ");
//remove "
size_t len = strlen(str);
str[len-1] = 0;
printf("'%s'\n", str + 1);//ignore first character or use memmove
free(str);
}
return 0;
}
I'm trying to write a code that goes through a given string using a pointer to parse it.
The original code I wrote worked fine but it was... redundant so I tried making it into a function call to make it more concise. Here is what i have:
char inputArray[300];
char buffer[300];
char username[100];
char password[100];
char name[100];
int i=0;
void repeat(char *to)
{
while(*to!='=')
{
to++;
}
}
void array(char *mm,char *tt)
{
i=0;
while(*tt!='+')
{
mm[i]=*tt;
tt++;
i++;
}
}
int main()
{
printf("give me the shit in this fashion: username=?+password=?+real=?\n");
scanf("%s",inputArray);
strcpy(buffer,inputArray);
char *tok=buffer;
repeat(tok);
tok++;
array(username,tok);
repeat(tok);
tok++;
array(password,tok);
tok++;
repeat(tok);
tok++;
array(name,tok);
}
For some reason it won't give me back the pointer array tok where it left off from the previous function call. why is that? it acts as if after calling it the pointer starts back from the beginning.
Functions receive copies of their arguments. Original arguments remain unaffected.
Giving something back has a special syntax in C: the return statement. Thus
char* repeat (char *to) // <- this function gives back a char*
{
while (*to != '=')
{
to++;
}
return to; // <- giving something back
}
Call it like this:
tok = repeat(tok);
Treat array in the same fashion.
Note 1, this function will result in *undefined behaviour if the string doesn't contain '='.
Note 2, it is also possible to pass a pointer to tok as the other answer suggests, but for sake of clarity it is only recommended to use this style when you need to return more than one thing from a function.
just change your repeat to this:
void repeat(char **to) {
while (**to != '=') {
(*to)++;
}
}
and call it like this:
repeat(&tok);
and always check for errors:
if (scanf("%299s", inputArray) != 1){
printf("incorrect input\n");
return 1;
}
and your sample code (and add check for errors in array and repeat to not go out of bounds):
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
char inputArray[300];
char buffer[300];
char username[300];
char password[300];
char name[300];
int i = 0;
void repeat(char **to) {
while (**to != '=') {
(*to)++;
}
}
void array(char *mm, char *tt){
i = 0;
while (*tt != '+') {
mm[i] = *tt;
tt++;
i++;
}
}
int main() {
printf("give me the shit in this fashion: username=?+password=?+real=?\n");
if (scanf("%299s", inputArray) != 1){
printf("incorrect input\n");
return 1;
}
inputArray[299] = 0;
strcpy(buffer, inputArray);
char *tok = buffer;
repeat(&tok);
tok++;
array(username, tok);
repeat(&tok);
tok++;
array(password, tok);
tok++;
repeat(&tok);
tok++;
array(name, tok);
}
and you may use this to not go out of bounds:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
char* read_str(char *src, char *dst){
char *p, *q;
p = src;
while (*p != 0 && *p != '=') p++;
if (*p == 0) {
*dst = 0;
return NULL; // '=' not found
}
p++;
q = p;
while (*q != 0 && *q != '+') q++;
//if (*q == 0) return NULL;// '+' not found
while (p <= q) *dst++ = *p++;
dst--;
*dst = 0;
q++;
return q;
}
#define MAX_LEN 100
int main() {
char username[MAX_LEN];
char password[MAX_LEN];
char name[MAX_LEN];
char inputArray[MAX_LEN] = "username=Alex+password=123+real=Alex";
char *p = inputArray;
p = read_str(p, username);
if (p == NULL)return 1; // error
p = read_str(p, password);
if (p == NULL)return 1; // error
read_str(p, name);
printf("username: %s \n", username);
printf("password: %s \n", password);
printf(" name: %s \n", name);
}
I have a string in my program where in which it need to be altered with another string value before a "/".
Source String : qos-tree/output_rate
Target String : qos-tree-2/output_rate
#include <stdio.h>
#include <string.h>
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main(void)
{
char str[256] = "qos-tree/output_rate";
char c = "a";
append(str, c);
printf("%s\n", str);
return 0;
}
This is what i have done so far,I think the logic is wrong here.Can anyone guide me to correct it?
Once the execution is completed the source string should have a "-2" before the "/"
void insert_before_ch(char *s, const char *ins, char c){
char *p = strchr(s, c);
if(p){
size_t len = strlen(ins);
memmove(p + len, p, strlen(p)+1);
memcpy(p, ins, len);
}
}
int main(void){
char str[256] = "qos-tree/output_rate";
insert_before_ch(str, "-2", '/');
printf("%s\n", str);
return 0;
}
In your attempt, you don't look for a slash and I do not see any "-2" anywhere.
Try this instead:
#include <stdio.h>
#include <string.h>
void append(char* s, char del, char* substring) {
char origin[256];
strcpy(origin, s);
int i = 0, j = 0, z = 0;
for(; origin[i]; ++i) {
if(origin[i] != del) {
s[j++] = origin[i];
} else {
for(; substring[z]; ++z) {
s[j++] = substring[z];
}
s[j++] = origin[i];
}
}
s[j] = '\0';
}
int main(void) {
char str[256] = "qos-tree/output_rate";
char del = '/';
char* substring = "-2";
append(str, del, substring);
printf("%s\n", str);
return 0;
}
The logic is that inside the function we use origin array to remember the actual contents of the array and then we copy from origin to s (which is the actual array of main()). If we find our delimiter del, then we copy the substring in that position and continuing with copying.
Note that the length of the array should be enough to store the resulted string. In this case, it is.
I think you should make your function work with dynamic allocation, because inserting characters into the string will make the resulting string larger, so this is my suggestion
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void insert(char **str, char chr, unsigned int position)
{
int length;
char *ptr;
if (str == NULL)
return;
length = strlen(*str);
if (position >= length)
return;
ptr = realloc(*str, 2 + length);
if (ptr == NULL)
return;
*str = ptr;
memmove(ptr + position + 1, ptr + position, length - position + 1);
ptr[position] = chr;
}
int main(void)
{
const char *source = "qos-tree/output_rate";
size_t length = strlen(source);
char *str = malloc(1 + length);
if (str == NULL)
return -1;
strcpy(str, source);
insert(&str, '-', 8);
insert(&str, '2', 9);
printf("%s\n", str);
free(str);
return 0;
}
first of all thist char c = "a" should be replace with this char c = 'a'; because c is a character not a string
as for your problem I didn't realy see the relation between what your code is doing with what you said you wanted to do , but here a piece of code to achieve what , I think , you want to do :
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void append(char* str , char c)
{
char firststr[60];
char therest[30];
strcpy(firststr , strtok(str , "/"));
strcpy(therest , strtok(NULL , "/"));
strcat(firststr , &c);
strcat(firststr , "/");
strcat(firststr , therest);
strcpy(str , firststr);
}
int main(void)
{
char str[60] = "qos-tree/output_rate";
char c = '2';
append(str , c);
printf("%s\n" , str);
}
there you go I think this is what you wanted to do you can modify the array sizes to fit your needs
I have a structure
typedef struct store
{
char name[11];
int age;
} store;
and a main function(below is part of it):
int main()
{
int i=0;
int inputs;
char line[100];
char name[11];
char command[11];
store read[3000];
while(i < 3000 && gets(line) != NULL)
{
int tempage;
inputs = sscanf(line, "%10s %10s %d", command, name, &tempage);
if (inputs == 3)
{
if (strcmp(command, "register") == 0)
{
strncpy(read[i].name, name,10);
read[i].age = tempage;
i++;
....
I need to modify it so that it can read a line of arbitrary length, and store the name from the line which is also a string of arbitrary length using malloc and realloc.
How should I approach this?
What you need to do is read the line in smaller increments, and resize your buffer as you go.
As an example (not tested and not meaning to be particularly elegant, just an example):
char *readline(FILE *f)
{
char *buf = NULL;
size_t bufsz = 0, len = 0;
int keep_going = 1;
while (keep_going)
{
int c = fgetc(f);
if (c == EOF || c == '\n')
{
c = 0; // we'll add zero terminator
keep_going = 0; // and terminate the loop afterwards
}
if (bufsz == len)
{
// time to resize the buffer.
//
void *newbuf = NULL;
if (!buf)
{
bufsz = 512; // some arbitrary starting size.
newbuf = malloc(bufsz);
}
else
{
bufsz *= 2; // issue - ideally you'd check for overflow here.
newbuf = realloc(buf, bufsz);
}
if (!newbuf)
{
// Allocation failure. Free old buffer (if any) and bail.
//
free(buf);
buf = NULL;
break;
}
buf = newbuf;
}
buf[len++] = c;
}
return buf;
}
Change the name[11] to *name;
Allocate memory for that everytime using malloc.
By the way, register is a keyword in C language. You can't use it like you did !
I think what you're looking for is:
char* name;
name = (char*)malloc(sizeof(char));
This alternative approach is similar to #asveikau's, but economize on the use of malloc() by copying on the stack.
Please do not use this for homework answer.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char * slurponeline(FILE *f, int s) {
const int size = 4096;
char buffer[size];
char * r;
int c,i=0;
while( i<size && (c = fgetc(f),c>=0 && c!='\n')) buffer[i++]=c;
if (0 == s && 0 == i) return 0;
r = (size==i)? slurponeline(f,s+size):malloc(s+i);
memcpy(r+s,buffer,i);
return r;
}
int main(int argc, char ** argv) {
FILE * f = fopen(argc>1?argv[1]:"a.out","rb");
char * a,*command,*commandend,*name,*nameend;
int age;
while (a = slurponeline(f,0)) {
char * p = a;
while (*p && *p == ' ') ++p; // skip blanks.
command = p;
while (*p && *p != ' ') ++p; // skip non-blanks.
commandend = p;
while (*p && *p == ' ') ++p; // skip blanks.
name = p;
while (*p && *p != ' ') ++p; // skip non-blanks.
nameend = p;
while (*p && *p == ' ') ++p; // skip blanks.
age = atoi(p);
*commandend=0;
*nameend=0;
printf("command: %s, name: %s, age: %d\n",command,name,age);
free(a);
}
}