473,396 Members | 2,033 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Design... the right way.


Hello All:
I am new to C and I have a program design question. Not only am I trying
to learn C but I'm also trying to pick up good habits. And I'm cocerned
with doing things the right and avoiding picking up bad habits.

The program I'm working on uses popen to read some pre-formatted output
from another program. The output looks like this.

line 0: persons_name
line 1: persons_last_name
line 2: .....

I then need to take each line assign it to a structure member. What
would be the simplest approach to find the member field from the line
loop count?

Michael Rosset
Jun 27 '08 #1
5 1273
mi**************@gmail.com said:
>
Hello All:
I am new to C and I have a program design question. Not only am I trying
to learn C but I'm also trying to pick up good habits. And I'm cocerned
with doing things the right and avoiding picking up bad habits.

The program I'm working on uses popen to read some pre-formatted output
from another program. The output looks like this.

line 0: persons_name
line 1: persons_last_name
line 2: .....

I then need to take each line assign it to a structure member. What
would be the simplest approach to find the member field from the line
loop count?
Given these rules:
1) you have at least one whole line in memory on each iteration of the loop
2) there is a colon in every line
3) the colon precedes the member field
4) there is nothing but whitespace between the colon and the member field
5) the member field contains no whitespace

you can get the member field like this:

char *fieldend = NULL;
char *colon = strchr(line, ':');
char *fieldstart = colon + 1;
while(isspace((unsigned char)*fieldstart))
{
++fieldstart;
}
fieldend = fieldstart + 1;
while(*fieldend != '\0' && !isspace((unsigned char)*fieldend))
{
++fieldend;
}

fieldend now points one byte beyond the member field. You can print the
exact contents of the member field like this:

printf("Field contents = [%.*s]\n", fieldend - fieldstart, fieldstart);

or, given at least 1 + fieldend - fieldstart bytes, you can make a string
out of it like this:

memcpy(target, fieldstart, fieldend - fieldstart);
target[fieldend - fieldstart] = '\0';

If that solves your problem, great. If it only moves you a bit closer to
it, what more do you need?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #2
On 26 Jun, 04:03, mike.rosset+g...@gmail.com wrote:
I am new to C and I have a program design question. Not only am I trying
to learn C but I'm also trying to pick up good habits.
good
:-)
And I'm cocerned
with doing things the right [way] and avoiding picking up bad habits.

The program I'm working on uses popen
popen() isn't actually standard C. It's standard Unix (Posix).
But your question becomes a standard C question if we assume you're
reading
from a stream (eg. opened by fopen())
to read some pre-formatted output
from another program. The output looks like this.
that is the *input* to your program looks like:
line 0: persons_name
line 1: persons_last_name
line 2: .....

I then need to take each line assign it to a structure member. What
would be the simplest approach to find the member field from the line
loop count?
I'm not sure. What are the structure members called?
When I read your question I thought persons_name
indicated a name and the actual input looked like

line 0: frodo
line 1: baggins

etc.

So you might be doing something like

void process_lines (struct Record *record)
{
char line [LARGEST_LINE];
char field [LARGEST_FIELD];
int line_count = 0;

while (read_line(line) == OK)
{
line_count++;
get_field (field, line);

switch (line_count)
{
1:
strcpy (record->person_name, field);
break;

2:
strcpy (record->persons_last_name, field);
break;

default:
fprintf (stderr, "Dire Straits!\n");
exit (EXIT_FAILURE);
}
}
}

which isn't exactly elegant...
The error handling is weak, the program is very trusting of the input
source.

I'd do get_field() more like this (a different approach to
RH's solution).

int get_field (char *field, const char *line)
{
int line_count
if (sscanf (line, "line %d: %s", &line_count, field) != 2)
return PARSE_ERROR;

return OK;
}

Could you explain your problem in more detail?
--
Nick Keighley

/*
- Note:
- I wanted to put a check in getGuiExtract(), but it's a void
method, inherited from the father of the father of the father of
the
[...]
the father of the father of the father of the father of the
father ...

So I can't modify its interface.
*/
[cry for help found in source code]
Jun 27 '08 #3
pete <pf*****@mindspring.comwrites:
>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX_FIELDS 19
#define PATH_MAX 10

enum pkg_vars {
pkgname,
pkgver
};

int main(void)
/*
** non prototype declarations
** is an obsolescent feature of the language
*/
{
int lines = 0;
char package[MAX_FIELDS][PATH_MAX];
/*
** A two dimensional array of char
*/
FILE *input = fopen("./test.sh", "r");
char line[PATH_MAX + 1];

if(input == NULL) {
perror("Error: running parser");
/*
** Nothing to fclose here
*/
exit(EXIT_FAILURE);
}
while(fgets(line, PATH_MAX, input)) {
line[strlen(line) - 1 ] = '\0';
if(lines < MAX_FIELDS) {
strcpy(package[lines], line);
}
lines++;
}
printf("name = %s\n", package[pkgname]);
printf("pkgver = %s\n", package[pkgver]);
printf("total = %d\n", lines);
/*
** A portable text stream, ends in a newline character.
*/
fclose(input);
return 0;
}

Pete, thanks for your response. Thank you for for your suggestions, all
of them make sense. I have a couple of questionsi. When you say "non
prototype declarations" you mean I should declare void as a parmater, it
not to be assumed.

Also I'm not sure what you mean by a portable stream should end in a
newline. Does that mean I should'nt remove it from line or I should copy
the line then remove it?

Mike Rosset
Jun 27 '08 #4

<mi**************@gmail.comwrote in message
news:87************@gmail.com...
pete <pf*****@mindspring.comwrites:
>>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX_FIELDS 19
#define PATH_MAX 10

enum pkg_vars {
pkgname,
pkgver
};

int main(void)
/*
** non prototype declarations
** is an obsolescent feature of the language
*/
{
int lines = 0;
char package[MAX_FIELDS][PATH_MAX];
/*
** A two dimensional array of char
*/
FILE *input = fopen("./test.sh", "r");
char line[PATH_MAX + 1];

if(input == NULL) {
perror("Error: running parser");
/*
** Nothing to fclose here
*/
exit(EXIT_FAILURE);
}
while(fgets(line, PATH_MAX, input)) {
line[strlen(line) - 1 ] = '\0';
if(lines < MAX_FIELDS) {
strcpy(package[lines], line);
}
lines++;
}
printf("name = %s\n", package[pkgname]);
printf("pkgver = %s\n", package[pkgver]);
printf("total = %d\n", lines);
/*
** A portable text stream, ends in a newline character.
*/
fclose(input);
return 0;
}


Pete, thanks for your response. Thank you for for your suggestions, all
of them make sense. I have a couple of questionsi. When you say "non
prototype declarations" you mean I should declare void as a parmater, it
not to be assumed.
int f(); /* declaration; does not specify parameters */
/* in C, an empty parameter list means 'not specified' */

int f(int a, char b); /* declaration; also a prototype (specifies
/* arguments)

int f(void); /* declaration/prototype: specific about arguments */
/* (in this case there are none */
>
Also I'm not sure what you mean by a portable stream should end in a
newline. Does that mean I should'nt remove it from line or I should copy
the line then remove it?
You can remove and put it back all you like, but what he's
saying is that the very last character in the stream should
be a newline ('\n').

-Mike
Jun 27 '08 #5
On Thu, 26 Jun 2008 15:27:48 GMT, "Bartc" <bc@freeuk.comwrote:
>
<mi**************@gmail.comwrote in message
news:87************@gmail.com...
The data format looks more like this

Frodo
Baggins
Hobbit

I vaguely remember Bilbo Baggins, so are these first names or last names?
<OT highly summarizedFrodo is indeed (fictionally) the first name of
Bilbo's honorary nephew and heir, who thus becomes the 'ring-bearer'
to take the One Ring to Mount Doom to be destroyed, through (nearly
all of) the _Lord of the Rings_ trilogy. I can imagine how you might
have ignored the books -- not forgive, just imagine <G-- but totally
missing three _huge_ Hollywood movies is quite an accomplishment. </>
/* popen? *waves hand* yes its fopen, continue on your way.*/
FILE *input = popen("./test.sh", "r");

I'm not familar with popen, from the docs it doesn't seem appropriate. Try
fopen().
OP previously said he wants this program to parse _the output of
running a script namely test.sh_ so it's very appropriate. But OT.
(But the issues of parsing and storing are mostly the same whether the
input comes from a running script or a plain file, and hence ontopic.
The only obvious exception would be if you wanted to rewind or
otherwise reposition in the input, which fails for a pipe; but then in
Standard C it may fail even for a 'real' file -- if any such.)

- formerly david.thompson1 || achar(64) || worldnet.att.net
Jul 7 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

36
by: Andrea Griffini | last post by:
I did it. I proposed python as the main language for our next CAD/CAM software because I think that it has all the potential needed for it. I'm not sure yet if the decision will get through, but...
33
by: Joe | last post by:
I'm designing a company website. I'm relatively new to CSS and I'm having trouble creating what seems to me a very simple design: - body background: fixed full page image - banner: fixed, 100...
6
by: Jacek Dziedzic | last post by:
Hello! First of all please forgive me for not posting a compilable snippet, but rather a simplified piece of code with the unimportant details left out. Let's say I have two classes...
11
by: John Fly | last post by:
I'm working on a large project(from scratch). The program is essentially a data file processor, the overall view is this: A data file is read in, validated and stored in a memory structure...
5
by: A_M_IS | last post by:
Dear valuable experts, I truly hope than You can suggest for me Your ideas how to resolve design. I developing relative small Access VB tool, for single user use only. Access version 2003, but db...
0
by: YellowFin Announcements | last post by:
Introduction Usability and relevance have been identified as the major factors preventing mass adoption of Business Intelligence applications. What we have today are traditional BI tools that...
17
by: roN | last post by:
Hi, I'm creating a Website with divs and i do have some troubles, to make it looking the same way in Firefox and IE (tested with IE7). I checked it with the e3c validator and it says: " This...
19
by: adriancico | last post by:
Hi I am working on a python app, an outliner(a window with a TreeCtrl on the left to select a document, and a RichTextBox at the right to edit the current doc). I am familiarized with OOP...
19
by: neelsmail | last post by:
Hi, I have been working on C++ for some time now, and I think I have a flair for design (which just might be only my imagination over- stretched.. :) ). So, I tried to find a design...
9
by: AceKnocks | last post by:
I am working on a framework design problem in which I have to design a C++ based framework capable of solving three puzzles for now but actually it should work with a general puzzle of any kind and I...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.