Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #112706 > unrolled thread
| Started by | DFS <nospam@dfs.com> |
|---|---|
| First post | 2017-06-20 12:48 -0400 |
| Last post | 2017-06-21 15:10 +0100 |
| Articles | 20 on this page of 39 — 10 participants |
Back to article view | Back to comp.lang.c
Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 12:48 -0400
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-20 18:08 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-21 09:32 -0400
Re: Warning: assignment from incompatible pointer type scott@slp53.sl.home (Scott Lurndal) - 2017-06-21 13:48 +0000
Re: Warning: assignment from incompatible pointer type Richard Heathfield <rjh@cpax.org.uk> - 2017-06-20 18:15 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 18:00 -0400
Re: Warning: assignment from incompatible pointer type "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 18:47 -0400
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-21 00:10 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 19:56 -0400
Re: Warning: assignment from incompatible pointer type "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 13:23 -0400
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 18:59 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-20 19:23 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 18:59 -0400
Re: Warning: assignment from incompatible pointer type Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2017-06-20 19:46 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-21 02:05 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 21:37 -0400
Re: Warning: assignment from incompatible pointer type Richard Heathfield <rjh@cpax.org.uk> - 2017-06-21 09:25 +0100
Re: Warning: assignment from incompatible pointer type David Brown <david.brown@hesbynett.no> - 2017-06-21 13:35 +0200
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-21 22:30 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-22 11:03 +0100
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 11:10 +0100
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 11:42 +0100
Re: Warning: assignment from incompatible pointer type David Brown <david.brown@hesbynett.no> - 2017-06-22 13:49 +0200
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 14:40 +0100
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 17:00 +0100
Re: Warning: assignment from incompatible pointer type David Brown <david.brown@hesbynett.no> - 2017-06-22 20:08 +0200
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-22 15:46 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-22 14:00 +0100
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 14:38 +0100
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-22 17:26 +0100
Re: Warning: assignment from incompatible pointer type Keith Thompson <kst-u@mib.org> - 2017-06-22 10:21 -0700
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 18:26 +0100
Re: Warning: assignment from incompatible pointer type David Brown <david.brown@hesbynett.no> - 2017-06-22 20:41 +0200
Re: Warning: assignment from incompatible pointer type Richard Heathfield <rjh@cpax.org.uk> - 2017-06-22 19:59 +0100
Re: Warning: assignment from incompatible pointer type Keith Thompson <kst-u@mib.org> - 2017-06-22 12:28 -0700
Re: Warning: assignment from incompatible pointer type Jerry Stuckle <jstucklex@attglobal.net> - 2017-06-21 09:49 -0400
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-21 10:36 -0400
Re: Warning: assignment from incompatible pointer type Jerry Stuckle <jstucklex@attglobal.net> - 2017-06-21 14:15 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-21 15:10 +0100
Page 1 of 2 [1] 2 Next page →
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-20 12:48 -0400 |
| Subject | Warning: assignment from incompatible pointer type |
| Message-ID | <Mlc2B.23027$xk.11193@fx39.iad> |
Why am I getting this warning?
char groups[100][20];
int g=0;
sprintf(uname,"%s",data[0][1]);
strcpy(groups[g],uname);
for(i=1;i<lines;i++)
{
sprintf(dname,"%s",data[i][1]);
if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE
{
strncpy(groups[g++],dname,strlen(dname));
}
}
That line passes the array 'groups' to a function to check if dname is
in the array:
int iteminarray(char *arr[], int size, char *theval)
{
int found=1;
for (int j=0;j<=size;j++)
{
if(strcmp(arr[j],theval)==0)
{
found=0;
break;
}
}
return found;
}
[toc] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-20 18:08 +0100 |
| Message-ID | <iEc2B.10580$3y7.7098@fx35.am4> |
| In reply to | #112706 |
On 20/06/2017 17:48, DFS wrote:
> Why am I getting this warning?
>
>
> char groups[100][20];
> int g=0;
> sprintf(uname,"%s",data[0][1]);
> strcpy(groups[g],uname);
>
> for(i=1;i<lines;i++)
> {
> sprintf(dname,"%s",data[i][1]);
> if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE
> {
> strncpy(groups[g++],dname,strlen(dname));
> }
> }
>
>
> That line passes the array 'groups' to a function to check if dname is
> in the array:
>
>
> int iteminarray(char *arr[], int size, char *theval)
> {
> int found=1;
> for (int j=0;j<=size;j++)
> {
> if(strcmp(arr[j],theval)==0)
> {
> found=0;
> break;
> }
> }
> return found;
> }
What type is dname? Or uname? Or i?
You need to supply enough code that will demonstrate the problem to
someone else trying to compile it.
Also, is iteminarray() only defined after the call to it? If so, and
there is no forward declaration for it, then that can also give problems.
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-21 09:32 -0400 |
| Message-ID | <oids8h$7ot$4@dont-email.me> |
| In reply to | #112708 |
On 6/20/2017 1:08 PM, bartc wrote:
> On 20/06/2017 17:48, DFS wrote:
>> Why am I getting this warning?
>>
>>
>> char groups[100][20];
>> int g=0;
>> sprintf(uname,"%s",data[0][1]);
>> strcpy(groups[g],uname);
>>
>> for(i=1;i<lines;i++)
>> {
>> sprintf(dname,"%s",data[i][1]);
>> if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE
>> {
>> strncpy(groups[g++],dname,strlen(dname));
>> }
>> }
>>
>>
>> That line passes the array 'groups' to a function to check if dname is
>> in the array:
>>
>>
>> int iteminarray(char *arr[], int size, char *theval)
>> {
>> int found=1;
>> for (int j=0;j<=size;j++)
>> {
>> if(strcmp(arr[j],theval)==0)
>> {
>> found=0;
>> break;
>> }
>> }
>> return found;
>> }
>
> What type is dname? Or uname? Or i?
Here are some solid clues:
sprintf(dname,"%s",data[i][1]);
sprintf(uname,"%s",data[0][1]);
i++
> You need to supply enough code that will demonstrate the problem to
> someone else trying to compile it.
I usually do, but I figured you guys would spot the issue easily.
> Also, is iteminarray() only defined after the call to it? If so, and
> there is no forward declaration for it, then that can also give problems.
iteminarray() is defined before main().
I do it like this:
includes
defines
declarations (sometimes)
functions
main
Isn't that the "standard" order?
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-06-21 13:48 +0000 |
| Message-ID | <HOu2B.58805$OD2.18577@fx44.iad> |
| In reply to | #112770 |
DFS <nospam@dfs.com> writes: >On 6/20/2017 1:08 PM, bartc wrote: > >I do it like this: > >includes >defines >declarations (sometimes) >functions >main > >Isn't that the "standard" order? > There is no "standard" order, of course, other than that in general an identifier must be declared before it is used. It's also common to do: includes globals/statics (if any, to be avoided if possible) forward declarations (often these are in a header file) main functions
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-06-20 18:15 +0100 |
| Message-ID | <oibl12$kg5$1@dont-email.me> |
| In reply to | #112706 |
On 20/06/17 17:48, DFS wrote: > Why am I getting this warning? > > > char groups[100][20]; <snip> > if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE <snip> > > int iteminarray(char *arr[], int size, char *theval) 6.3.2(3): "Except when [several exceptions that don't apply here]...an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue..." So, because it's being used in a context that isn't one of the excepted contexts, the groups array in: if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE is treated just as if it were written like this: if (iteminarray(&groups[0],g,dname)!=0) //THROWS WARNING HERE Now, groups[0] has type char [20], so &groups[0] has type "pointer to char[20]", or char (*)[20]. But your function is: int iteminarray(char *arr[], int size, char *theval) And char (*)[20] is not the same as char *arr[], which is a mere shorthand for char **arr. That is, iteminarray() expects a pointer-to-pointer-to-char, but what you're giving it is pointer-to-array-of-20-char. These types are incompatible, hence your warning. It's a nuisance, I know. I've generally found that the quickest, simplest fix is to throw the whole darn thing into a struct and pass /that/ address around. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-20 18:00 -0400 |
| Message-ID | <oic5nu$eqm$1@dont-email.me> |
| In reply to | #112709 |
On 6/20/2017 1:15 PM, Richard Heathfield wrote: > On 20/06/17 17:48, DFS wrote: >> Why am I getting this warning? >> >> >> char groups[100][20]; > <snip> >> if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE > <snip> >> >> int iteminarray(char *arr[], int size, char *theval) > > > 6.3.2(3): "Except when [several exceptions that don't apply here]...an > expression that has type ‘‘array of type’’ is converted to an expression > with type ‘‘pointer to type’’ that points to the initial element of the > array object and is not an lvalue..." Which reference does this come from ? > So, because it's being used in a context that isn't one of the excepted > contexts, the groups array in: > > if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE > > is treated just as if it were written like this: > > if (iteminarray(&groups[0],g,dname)!=0) //THROWS WARNING HERE > > Now, groups[0] has type char [20], so &groups[0] has type "pointer to > char[20]", or char (*)[20]. > > But your function is: > > int iteminarray(char *arr[], int size, char *theval) > > And char (*)[20] is not the same as char *arr[], which is a mere > shorthand for char **arr. That is, iteminarray() expects a > pointer-to-pointer-to-char, but what you're giving it is > pointer-to-array-of-20-char. These types are incompatible, hence your > warning. K & R: sadistic language designers. > It's a nuisance, I know. I've generally found that the quickest, > simplest fix is to throw the whole darn thing into a struct and pass > /that/ address around. I haven't used structs yet in C, but I'm going to keep moving forward and learning. Thanks for the answer.
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-06-20 18:47 -0400 |
| Message-ID | <ea0e1089-60f3-edbf-ddd6-97eec126a201@verizon.net> |
| In reply to | #112743 |
On 06/20/2017 06:00 PM, DFS wrote:
> On 6/20/2017 1:15 PM, Richard Heathfield wrote:
...
>> 6.3.2(3): "Except when [several exceptions that don't apply here]...an
>> expression that has type ‘‘array of type’’ is converted to an expression
>> with type ‘‘pointer to type’’ that points to the initial element of the
>> array object and is not an lvalue..."
>
> Which reference does this come from ?
The C standard: ISO/IEC 9899. The latest version is ISO/IEC 9899:2011,
and a free draft version of the standard that is almost identical to the
final standard my be found at
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>
>> So, because it's being used in a context that isn't one of the excepted
>> contexts, the groups array in:
>>
>> if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE
>>
>> is treated just as if it were written like this:
>>
>> if (iteminarray(&groups[0],g,dname)!=0) //THROWS WARNING HERE
>>
>> Now, groups[0] has type char [20], so &groups[0] has type "pointer to
>> char[20]", or char (*)[20].
>>
>> But your function is:
>>
>> int iteminarray(char *arr[], int size, char *theval)
>>
>> And char (*)[20] is not the same as char *arr[], which is a mere
>> shorthand for char **arr. That is, iteminarray() expects a
>> pointer-to-pointer-to-char, but what you're giving it is
>> pointer-to-array-of-20-char. These types are incompatible, hence your
>> warning.
>
>
> K & R: sadistic language designers.
The weren't being sadistic, they were trying to make things convenient,
according to their ideas of convenience (which you're free to disagree
with). You're clearly not very experienced with C. Given more
experience, you might end up agreeing with them.
The key point was the decision to not allow arrays to be passed around
as arguments. As a result, one of the most common things you'll need to
do with an array is generate a pointer to the first element of that
array. K&R makes it easy to generate such a pointer, because any
reference to the array gets implicitly converted to such a pointer.
Similarly, since it's not possible for a function to receive an array as
a parameter, it was decided to make a declaration of a parameter that
looks like it's declaring an array, actually become a declaration of a
pointer to the type of the first element of that array. As a result, you
can simply write:
int array[1024];
void func(int input[1024]);
func(array);
Without those features, you'd have to write:
void func(int *input);
func(&array[0]);
You'd be writing &array[0] VERY frequently.
This is indeed confusing, and if you make the mistake of paying too much
attention to BartC, it might up seeming overwhelmingly confusing.
However, most C programmers adapt to these concepts far more easily than
BartC has.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-21 00:10 +0100 |
| Message-ID | <OXh2B.8949$r55.8699@fx38.am4> |
| In reply to | #112745 |
On 20/06/2017 23:47, James R. Kuyper wrote:
> On 06/20/2017 06:00 PM, DFS wrote:
>> K & R: sadistic language designers.
>
> Similarly, since it's not possible for a function to receive an array as
> a parameter, it was decided to make a declaration of a parameter that
> looks like it's declaring an array, actually become a declaration of a
> pointer to the type of the first element of that array. As a result, you
> can simply write:
>
> int array[1024];
> void func(int input[1024]);
> func(array);
>
> Without those features, you'd have to write:
>
> void func(int *input);
> func(&array[0]);
>
> You'd be writing &array[0] VERY frequently.
You end up writing 'array' instead. But 'array' has type 'array of int'.
The parameter has type 'pointer to int'. A subtle conversion is done to
'array' to make it 'pointer to int'.
In the meantime, neither an array nor pointer to an array is being
passed. In fact, no array is involved at all. You can pass an actual
pointer to one int, and that's fine, even if it's wrong/
> This is indeed confusing, and if you make the mistake of paying too much
> attention to BartC, it might up seeming overwhelmingly confusing.
> However, most C programmers adapt to these concepts far more easily than
> BartC has.
There are less confusing ways of doing it:
int array[1024]; // array of int as before
void func(int (*input)[]); // function now takes pointer to array
funct(&array); // & turns an array type into a pointer
// to array
All is now more logical.
But don't pay any attention to me. You are expected to program in C like
everyone else.
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-20 19:56 -0400 |
| Message-ID | <oiccge$349$1@dont-email.me> |
| In reply to | #112745 |
On 6/20/2017 6:47 PM, James R. Kuyper wrote:
> On 06/20/2017 06:00 PM, DFS wrote:
>> On 6/20/2017 1:15 PM, Richard Heathfield wrote:
> ...
>>> 6.3.2(3): "Except when [several exceptions that don't apply here]...an
>>> expression that has type ‘‘array of type’’ is converted to an expression
>>> with type ‘‘pointer to type’’ that points to the initial element of the
>>> array object and is not an lvalue..."
>>
>> Which reference does this come from ?
>
>
> The C standard: ISO/IEC 9899. The latest version is ISO/IEC 9899:2011,
> and a free draft version of the standard that is almost identical to the
> final standard my be found at
> <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>
Thanks.
Or you can buy it for USD $203.14
https://www.iso.org/standard/57853.html
>>> So, because it's being used in a context that isn't one of the excepted
>>> contexts, the groups array in:
>>>
>>> if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE
>>>
>>> is treated just as if it were written like this:
>>>
>>> if (iteminarray(&groups[0],g,dname)!=0) //THROWS WARNING HERE
>>>
>>> Now, groups[0] has type char [20], so &groups[0] has type "pointer to
>>> char[20]", or char (*)[20].
>>>
>>> But your function is:
>>>
>>> int iteminarray(char *arr[], int size, char *theval)
>>>
>>> And char (*)[20] is not the same as char *arr[], which is a mere
>>> shorthand for char **arr. That is, iteminarray() expects a
>>> pointer-to-pointer-to-char, but what you're giving it is
>>> pointer-to-array-of-20-char. These types are incompatible, hence your
>>> warning.
>>
>>
>> K & R: sadistic language designers.
>
> The weren't being sadistic, they were trying to make things convenient,
> according to their ideas of convenience (which you're free to disagree
> with). You're clearly not very experienced with C. Given more
> experience, you might end up agreeing with them.
I'm experienced enough to write a pivot table engine (if you're not
familiar they're found in spreadsheets). It's my first "real" C
program. Code is below. Feel free to praise, savage or ignore it.
> The key point was the decision to not allow arrays to be passed around
> as arguments. As a result, one of the most common things you'll need to
> do with an array is generate a pointer to the first element of that
> array. K&R makes it easy to generate such a pointer, because any
> reference to the array gets implicitly converted to such a pointer.
>
> Similarly, since it's not possible for a function to receive an array as
> a parameter, it was decided to make a declaration of a parameter that
> looks like it's declaring an array, actually become a declaration of a
> pointer to the type of the first element of that array. As a result, you
> can simply write:
>
> int array[1024];
> void func(int input[1024]);
> func(array);
>
> Without those features, you'd have to write:
>
> void func(int *input);
> func(&array[0]);
>
> You'd be writing &array[0] VERY frequently.
>
> This is indeed confusing, and if you make the mistake of paying too much
> attention to BartC, it might up seeming overwhelmingly confusing.
> However, most C programmers adapt to these concepts far more easily than
> BartC has.
The first looks simpler.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
//#include <time.h>
#define MAX_ROWS 1000
#define MAX_COLUMNS 5
#define MAX_LABEL 25
//check for .csv extension
int csvext(char *fname)
{
const char *ext = strrchr(fname, '.');
if (!ext) {return -1;}
if (strcmp(ext + 1,"csv")!=0) {return -1;}
return 0;
}
//check for existence of item in array
int iteminarray(char (*arr)[20], int size, char *theval)
{
int found=1;
for (int j=0;j<=size;j++)
{if(strcmp(arr[j],theval)==0){found=0;break;}}
return found;
}
//count characters in a string
int countchr(char *str, char chr)
{int c=0,cnt=0;while(str[c]!='\0'){if(str[c]==chr){cnt++;}c++;}return cnt;}
//replace character in a string
void replace(char * str, char from, char to)
{int i=0;while(str[i]!='\0'){if(str[i]==from){str[i]=to;}i++;}}
int main (int argc, char *argv[])
{
//vars
_Bool verbose = 1;
int i=0, j=0, lines=0, k=0;
char filein[strlen(argv[1])];
char fileout[50] = "test.txt";
char line[200] = "";
char uname[50]="", dname[50]="";
FILE *fin, *fout;
//must have a .csv extension
strcpy(filein,argv[1]);
if(csvext(filein)!=0)
{printf(".csv file required");exit(0);}
//open .csv file
fin = fopen(filein,"r");
if(fin == NULL)
{
printf("Failed to open %s\n",filein);
return -1;
}
/* ##################### data validations #############################*/
//count columns of data in each line (commas + 1)
//accepts 2 3 or 4 columns of data
printf("\rvalidating...");
fgets(line,sizeof line, fin);
char separator = ',';
int headers = countchr(line,separator)+1;
if(headers==1||headers>4)
{
printf("Invalid data. Only 2 to 4 data fields allowed");
fclose(fin);
exit(0);
}
//# of data fields in each row must match # of headers
i=2;
while (fgets(line,sizeof line, fin)!= NULL)
{
if (countchr(line,separator)!=headers-1)
{
printf("Invalid data on line %d. Incorrect number of data
fields.",i);fclose(fin);
exit(0);
}
i++;
}
//store count of lines of data
lines = i-2;
//no data or too much data
if (lines==0)
{printf("No data");fclose(fin);exit(0);}
if (lines>MAX_ROWS)
{printf("Too much data. This program has a 1000-line
limit");fclose(fin);exit(0);}
//TODO make sure each row has data for all fields
//TODO must have at least one column of text and one column of numbers
//TODO dynamically size data and temp arrays to allow large datasets
char lbls[4][25];
char data[1000][5][25];
char temp[1000][100];
printf("\rvalidating...OK\n");
/* ##################### import data #############################*/
if(verbose) {printf("=======================================\n");}
//import labels (1st line)
fseek(fin, 0, SEEK_SET);
fgets(line,sizeof line, fin);
printf("%s",line);
replace(line,separator,' ');
if(headers==2){sscanf(line, "%s %s", &lbls[0],&lbls[1]);}
if(headers==3){sscanf(line, "%s %s %s", &lbls[0],&lbls[1],&lbls[2]);}
if(headers==4){sscanf(line, "%s %s %s %s",
&lbls[0],&lbls[1],&lbls[2],&lbls[3]);}
//import data to array
i=0;
rewind(fin);
fgets(line,sizeof line, fin);
while (fgets(line,sizeof line, fin)!= NULL)
{
if(verbose){printf("%d. %s",i+1,line);}
replace(line,separator,' ');
if(headers==2)
{sscanf(line, "%s %s", &data[i][1],&data[i][2]);
sprintf(uname,"%s", data[i][1]);}
if(headers==3)
{sscanf(line, "%s %s %s", &data[i][1],&data[i][2],&data[i][3]);
sprintf(uname,"%s %s", data[i][1],data[i][2]);}
if(headers==4)
{sscanf(line, "%s %s %s %s",
&data[i][1],&data[i][2],&data[i][3],&data[i][4]);
sprintf(uname,"%s %s %s", data[i][1],data[i][2],data[i][3]);
}
strncpy(data[i][0],uname,strlen(uname));
//printf("data[%d][1] = %s",i,data[i][1]);
//printf("uname %s",uname);
i++;
}
printf("Imported %d fields (%d rows of data)\n",headers,lines);
/* ################## display sorted data ##########################*/
if(verbose)
{
printf("=======================================\nsorted data\n");
//import data to temp array (lines 2+)
i=0;
rewind(fin);
fgets(line,sizeof line, fin);
while (fgets(line,sizeof line, fin)!= NULL)
{strncpy(temp[i],line,strlen(line));i++;}
//sort
char temp2[1000];
for (i = 0; i < lines-1 ; i++)
{
for (j = i + 1; j < lines; j++)
{
if (strcmp(temp[i], temp[j]) > 0)
{
strcpy(temp2, temp[i]);
strcpy(temp[i], temp[j]);
strcpy(temp[j], temp2);
}
}
}
//print - restart numbering with each change in 1st character
j=1;
char ch = temp[0][0];
printf("%d. %s",j, temp[0]);
for(i=1;i<lines;i++)
{
if (ch==temp[i][0]){j++;} else {ch=temp[i][0];j=1;}
printf("%d. %s",j, temp[i]);
}
printf("====================================================\n");
}
//finished with input file
fclose(fin);
//TODO offer user pivot options
/* ########## summary numbers for each group ##############*/
char groups[100][20];
int g=0;
//add first group to array
sprintf(dname,"%s",data[0][1]);
strcpy(groups[g],dname);
//get other unique groups in data
for(i=1;i<lines;i++)
{
sprintf(dname,"%s",data[i][1]);
if (iteminarray(groups,g,dname)!=0)
{g++;strcpy(groups[g],dname);}
}
g++;
//sort groups
//for(i=0;i<g;i++) {printf("%d. %s\n",i,groups[i]);}
char groups2[g];
for (i = 0; i < g-1 ; i++)
{
for (j = i + 1; j < g; j++)
{
if (strcmp(groups[i], groups[j]) > 0)
{
strcpy(groups2, groups[i]);
strcpy(groups[i], groups[j]);
strcpy(groups[j], groups2);
}
}
}
//for(i=0;i<g;i++) {printf("%d. %s\n",i,groups[i]);}
//calc summary for each group
//calc totals for all groups
//add data to arrays
char s[100][7][50]; // summary array: #,Name,Rows,Total,Min,Max,Agv
char p[10][100][50]; // pivot array: rows in summary become columns
char val;
int u=g; //g = number of unique groups
int utot,urows,umin,umax;
int ttot=0,trows=0;
int tmin = strtol(data[0][headers],NULL,10) * 1000;
int tmax = 0;
for(g=0;g<u;g++)
{
sprintf(uname,"%s",groups[g]);
utot=0;urows=0;
umin = strtol(data[0][headers],NULL,10) * 1000;
umax = 0;
for(i=0;i<lines;i++)
{
if (strcmp(uname,data[i][0])==0)
{
j = strtol(data[i][headers],NULL,10);
if(j < umin){umin = j;}
if(j > umax){umax = j;}
utot+=j; ttot+=j; urows++; trows++;
}
}
//add group results to summary array
sprintf(s[g][0], "%d", g);
sprintf(s[g][1], "%s", uname);
sprintf(s[g][2], "%d", urows);
sprintf(s[g][3], "%d", utot);
sprintf(s[g][4], "%d", umin);
sprintf(s[g][5], "%d", umax);
sprintf(s[g][6], "%.2f", utot/(float)urows);
//add group results to pivot array
sprintf(p[0][g+1], "%s", uname);
sprintf(p[1][g+1], "%d", urows);
sprintf(p[2][g+1], "%d", utot);
sprintf(p[3][g+1], "%d", umin);
sprintf(p[4][g+1], "%d", umax);
sprintf(p[5][g+1], "%.2f", utot/(float)urows);
//overall min/max
if(umin < tmin){tmin = umin;}
if(umax > tmax){tmax = umax;}
}
//add total row to summary array
sprintf(s[g][0], "%d", g+1);
sprintf(s[g][1], "%s", "Total");
sprintf(s[g][2], "%d", trows);
sprintf(s[g][3], "%d", ttot);
sprintf(s[g][4], "%d", tmin);
sprintf(s[g][5], "%d", tmax);
sprintf(s[g][6], "%.2f", ttot/(float)trows);
//add total column to pivot array
sprintf(p[0][g+1], "%s", "Total");
sprintf(p[1][g+1], "%d", trows);
sprintf(p[2][g+1], "%d", ttot);
sprintf(p[3][g+1], "%d", tmin);
sprintf(p[4][g+1], "%d", tmax);
sprintf(p[5][g+1], "%.2f", ttot/(float)trows);
//add labels column to pivot array
//strcpy(p[0][0], "Stat");
strcpy(p[1][0], "Rows");
strcpy(p[2][0], lbls[headers-1]);
strcpy(p[3][0], "Min");
strcpy(p[4][0], "Max");
strcpy(p[5][0], "Avg");
//print summary
printf("Summary\n");
printf("Name Rows %s Min Max Avg\n",lbls[headers-1]);
for(i=0;i<g+1;i++)
{printf("%-10s %4s %4s %4s %4s
%5s\n",s[i][1],s[i][2],s[i][3],s[i][4],s[i][5],s[i][6]);}
printf("====================================================\n");
//print pivot (needs some work)
printf("Pivot %s\n",lbls[0]);
for(i=0;i<6;i++)
{
printf("%-7s %5s %5s %5s %5s
%5s\n",p[i][0],p[i][1],p[i][2],p[i][3],p[i][4],p[i][5]);
//printf("\r%-7s ",p[i][0]);
//for(j=1;j<6;j++)
//{printf("%6s",p[j][i]);}
}
printf("====================================================\n");
//write pivot results to .csv file
//fout = fopen(fileout,"w");
//fclose(fout);
return 0;
}
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-06-20 13:23 -0400 |
| Message-ID | <cae08755-4a4b-7c50-223e-aedbdd095cf0@verizon.net> |
| In reply to | #112706 |
On 06/20/2017 12:48 PM, DFS wrote: > Why am I getting this warning? > > > char groups[100][20]; > int g=0; ... > if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE As a general rule, it's a good idea to post the exact text of the warning message that you're asking about. That would make it much easier for us to help you. "groups" is an array containing 100 elements, with the type of each element being char[20]. In C, you can't actually pass an array as an argument to a function. As an lvalue of array type, in most contexts (this being one of them), "groups" gets converted into a pointer to the first element of that array, and the result of that conversion has the type char (*)[20], which is something that you can pass to a function. ... > That line passes the array 'groups' to a function to check if dname is > in the array: > > > int iteminarray(char *arr[], int size, char *theval) This declares arr to be an array of unknown length, with each element of that array being a pointer to char. In C, you can't actually pass arrays as arguments. Declarations of parameters that appear to declare them as arrays get adjusted so they are actually declarations of a pointer to the first element of the array. In this case, that means arr has the type char**, a pointer to a pointer to char. It is therefore not compatible with an argument which has the type "pointer to an array of 20 char". If you change the declaration to char(*arr)[20], your code should work as intended.
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-20 18:59 -0400 |
| Message-ID | <oic95k$qkf$2@dont-email.me> |
| In reply to | #112711 |
On 6/20/2017 1:23 PM, James R. Kuyper wrote: > If you change the declaration to char(*arr)[20], your code should work > as intended. And it does! Thanks
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-20 19:23 +0100 |
| Message-ID | <8760fqbjrr.fsf@bsb.me.uk> |
| In reply to | #112706 |
DFS <nospam@dfs.com> writes:
> Why am I getting this warning?
>
>
> char groups[100][20];
> int g=0;
> sprintf(uname,"%s",data[0][1]);
> strcpy(groups[g],uname);
>
> for(i=1;i<lines;i++)
> {
> sprintf(dname,"%s",data[i][1]);
> if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE
> {
> strncpy(groups[g++],dname,strlen(dname));
Take care. This may result in no terminating null (and it wastes time
filling with zeros). If you want a string (as you seem to since you
test with strcmp not strncmp) use the proper string function to copy
the data about as you do 7 lines up.
> }
> }
>
>
> That line passes the array 'groups' to a function to check if dname is in the array:
>
> int iteminarray(char *arr[], int size, char *theval)
The type is wrong, that's all. You want
int iteminarray(char (*arr)[20], int size, char *theval)
I won't explain more because other have done so already, but I'm happy
to if need be.
> {
> int found=1;
> for (int j=0;j<=size;j++)
> {
> if(strcmp(arr[j],theval)==0)
> {
> found=0;
> break;
> }
> }
> return found;
> }
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-20 18:59 -0400 |
| Message-ID | <oic978$qkf$3@dont-email.me> |
| In reply to | #112718 |
On 6/20/2017 2:23 PM, Ben Bacarisse wrote:
> DFS <nospam@dfs.com> writes:
>
>> Why am I getting this warning?
>>
>>
>> char groups[100][20];
>> int g=0;
>> sprintf(uname,"%s",data[0][1]);
>> strcpy(groups[g],uname);
>>
>> for(i=1;i<lines;i++)
>> {
>> sprintf(dname,"%s",data[i][1]);
>> if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE
>> {
>> strncpy(groups[g++],dname,strlen(dname));
>
> Take care. This may result in no terminating null (and it wastes time
> filling with zeros). If you want a string (as you seem to since you
> test with strcmp not strncmp) use the proper string function to copy
> the data about as you do 7 lines up.
Done.
Also, something "strange" happens on that line:
strncpy(groups[g++],dname,strlen(dname));
g++ doesn't increment g before adding dname to groups. The initial
value I added to groups[0] is overwritten.
You have to do g++; before the string copy for it to work the way you
expect it to work.
g++;
strncpy(groups[g],dname,strlen(dname));
Is that odd to you?
Tiny C compiler on Windows (if that matters)
>> That line passes the array 'groups' to a function to check if dname is in the array:
>>
>> int iteminarray(char *arr[], int size, char *theval)
>
> The type is wrong, that's all. You want
>
> int iteminarray(char (*arr)[20], int size, char *theval)
>
> I won't explain more because other have done so already, but I'm happy
> to if need be.
That was all it took - the code runs 'perfectly' now - meaning it now
gets a unique list of values from an array
In python I would've said groups = sorted(set(data)) and been done with
it!
[toc] | [prev] | [next] | [standalone]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2017-06-20 19:46 -0400 |
| Message-ID | <oicbug$29r$1@dont-email.me> |
| In reply to | #112747 |
DFS wrote:
> On 6/20/2017 2:23 PM, Ben Bacarisse wrote:
>> DFS <nospam@dfs.com> writes:
>>
>>> Why am I getting this warning?
>>>
>>>
>>> char groups[100][20];
>>> int g=0;
>>> sprintf(uname,"%s",data[0][1]);
>>> strcpy(groups[g],uname);
>>>
>>> for(i=1;i<lines;i++)
>>> {
>>> sprintf(dname,"%s",data[i][1]);
>>> if (iteminarray(groups,g,dname)!=0) //THROWS WARNING HERE
>>> {
>>> strncpy(groups[g++],dname,strlen(dname));
>>
>> Take care. This may result in no terminating null (and it wastes time
>> filling with zeros). If you want a string (as you seem to since you
>> test with strcmp not strncmp) use the proper string function to copy
>> the data about as you do 7 lines up.
>
> Done.
>
> Also, something "strange" happens on that line:
>
> strncpy(groups[g++],dname,strlen(dname));
>
> g++ doesn't increment g before adding dname to groups.
Of course not,
g++
is a postfix expression; the value used in the groups[] subscript
calculation will be the value of g prior to the increment. That's what g++
means.
If you wanted g incremented /first/, you should have used
++g
as in
strncpy(groups[++g],dname,strlen(dname));
> The initial
> value I added to groups[0] is overwritten.
>
> You have to do g++; before the string copy for it to work the way you
> expect it to work.
>
> g++;
> strncpy(groups[g],dname,strlen(dname));
>
> Is that odd to you?
Not at all. That's how a postfix increment is supposed to work.
[snip]
--
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-21 02:05 +0100 |
| Message-ID | <87o9ti9mlt.fsf@bsb.me.uk> |
| In reply to | #112747 |
DFS <nospam@dfs.com> writes: <snip> > In python I would've said groups = sorted(set(data)) and been done > with it! Yes. Why are you using C? It looks like this is the kind of program at which a simple scripting language excels. (This is a genuine question. I'm interested in why people use C and for what. Often it's just to try it out, but maybe you have some other reason.) By the way, C also has a sort function called qsort. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-20 21:37 -0400 |
| Message-ID | <oicier$fvg$2@dont-email.me> |
| In reply to | #112751 |
On 6/20/2017 9:05 PM, Ben Bacarisse wrote:
> DFS <nospam@dfs.com> writes:
> <snip>
>> In python I would've said groups = sorted(set(data)) and been done
>> with it!
>
> Yes. Why are you using C? It looks like this is the kind of program at
> which a simple scripting language excels. (This is a genuine question.
> I'm interested in why people use C and for what. Often it's just to try
> it out, but maybe you have some other reason.)
Mainly I love the blazing execution speed of C.
I want to learn it well enough to understand or modify various open
source code.
I like that it's 'close to the metal'.
Makes me a better programmer, too.
Currently I do it only as a hobby, but it would be nice to put on a
resume and be able to use C on the job if needed.
Why do you use C?
> By the way, C also has a sort function called qsort.
I tried qsort at one point and didn't like it.
I'd rather:
char groups2[g];
for (i = 0; i < g-1 ; i++)
{
for (j = i + 1; j < g; j++)
{
if (strcmp(groups[i], groups[j]) > 0)
{
strcpy(groups2, groups[i]);
strcpy(groups[i], groups[j]);
strcpy(groups[j], groups2);
}
}
}
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-06-21 09:25 +0100 |
| Message-ID | <oidab6$d83$1@dont-email.me> |
| In reply to | #112752 |
On 21/06/17 02:37, DFS wrote:
<snip>
>> By the way, C also has a sort function called qsort.
>
> I tried qsort at one point and didn't like it.
> I'd rather:
>
> char groups2[g];
> for (i = 0; i < g-1 ; i++)
> {
> for (j = i + 1; j < g; j++)
> {
> if (strcmp(groups[i], groups[j]) > 0)
> {
> strcpy(groups2, groups[i]);
> strcpy(groups[i], groups[j]);
> strcpy(groups[j], groups2);
> }
> }
> }
For someone who likes "blazing execution speed", it seems odd that you
should choose an O(n^2) algorithm when an O(n log n) algorithm is
available at no extra cost.
If it's speed you're after, replace the above code with a call to qsort.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-21 13:35 +0200 |
| Message-ID | <oidlf0$gne$1@dont-email.me> |
| In reply to | #112752 |
On 21/06/17 03:37, DFS wrote:
> On 6/20/2017 9:05 PM, Ben Bacarisse wrote:
>> DFS <nospam@dfs.com> writes:
>> <snip>
>>> In python I would've said groups = sorted(set(data)) and been done
>>> with it!
>>
>> Yes. Why are you using C? It looks like this is the kind of program at
>> which a simple scripting language excels. (This is a genuine question.
>> I'm interested in why people use C and for what. Often it's just to try
>> it out, but maybe you have some other reason.)
>
> Mainly I love the blazing execution speed of C.
>
The speed of a program comes from many things. The algorithm used is
often more important than the language, and the speed of the tool's
libraries can be a big effect. Python excels at string handling,
searching and sorting - in some cases a few lines of Python code will
run faster than a C program for the job. Of course C code /could/ be
faster - the standard Python system is written in C. But the sorting
code in Python's runtime libraries was written by experts, checked and
tested by experts, with huge amounts of testing and fine-tuning on
different systems and with different types of data. If you spend a
similar effort, you might get similar results - but would you put that
kind of effort into the C code?
So while C is often the best choice when you really need the fastest
code, that does not mean that writing in C makes your code fast or
faster than alternatives.
> I want to learn it well enough to understand or modify various open
> source code.
Open source code can be written in any one of dozens of languages -
though C is quite common. Understanding the code is often a lot more
than just understanding the language it is written in. Do you have
particular projects that interest you?
>
> I like that it's 'close to the metal'.
>
Ah, there you have a winner in C. It is as close to the metal as you
can get without assembly.
> Makes me a better programmer, too.
>
Agreed. You would also be a better programmer if you learned other
languages too - variety helps. But a reasonable understanding of C is a
good idea for a "general programmer".
> Currently I do it only as a hobby, but it would be nice to put on a
> resume and be able to use C on the job if needed.
>
To program in C professionally, you need to take your learning more
seriously than trial-and-error self learning. But that is fine for a
hobby, and if you feel you are getting the hang of it and like the
language, you can do a course to fill out the details and be ready to
work in C.
>
> Why do you use C?
>
Most of my work is small systems embedded programming, and C is simply
the most appropriate language for the job. It used to be more assembly,
and sometimes it is C++, but for the majority of this type of
programming, C is the right choice. It gives you "close to the metal"
programming while being far safer, and far more productive and portable
than assembly. There are C toolchains for every microcontroller, but
for many there are no other languages supported. Most existing code is
in C, and most embedded programmers work in C, so that in itself means C
is usually the best choice.
And I like C programming on such systems.
For PC programming, however, I mostly use Python - it gets the job done
faster.
>
>
>> By the way, C also has a sort function called qsort.
>
> I tried qsort at one point and didn't like it.
> I'd rather:
>
> char groups2[g];
> for (i = 0; i < g-1 ; i++)
> {
> for (j = i + 1; j < g; j++)
> {
> if (strcmp(groups[i], groups[j]) > 0)
> {
> strcpy(groups2, groups[i]);
> strcpy(groups[i], groups[j]);
> strcpy(groups[j], groups2);
> }
> }
> }
>
You are mixing up your array sizes and your counts here.
Apart from that, you have a bubble sort algorithm. That will run
quickly for small samples, but be a lot slower for bigger ones.
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-21 22:30 -0400 |
| Message-ID | <oif9q6$s7i$2@dont-email.me> |
| In reply to | #112759 |
On 6/21/2017 7:35 AM, David Brown wrote:
> On 21/06/17 03:37, DFS wrote:
>> On 6/20/2017 9:05 PM, Ben Bacarisse wrote:
>>> DFS <nospam@dfs.com> writes:
>>> <snip>
>>>> In python I would've said groups = sorted(set(data)) and been done
>>>> with it!
>>>
>>> Yes. Why are you using C? It looks like this is the kind of program at
>>> which a simple scripting language excels. (This is a genuine question.
>>> I'm interested in why people use C and for what. Often it's just to try
>>> it out, but maybe you have some other reason.)
>>
>> Mainly I love the blazing execution speed of C.
>>
>
> The speed of a program comes from many things. The algorithm used is
> often more important than the language, and the speed of the tool's
> libraries can be a big effect. Python excels at string handling,
> searching and sorting - in some cases a few lines of Python code will
> run faster than a C program for the job.
python is slow at everything I've ever tried. A sed line will execute
4x faster than python (say to do some word replacements or swaps). C is
20x faster on avg I would say.
But python is easy to learn, and has a big bunch of libraries. And I
love the python list comprehension.
One line to count the unique characters in a string.
msg = "Now is the time for all good men to come to the aid of their country"
for t in sorted(set([(x,msg.count(x)) for x in msg])):
print t[0],t[1]
> Of course C code /could/ be
> faster - the standard Python system is written in C. But the sorting
> code in Python's runtime libraries was written by experts, checked and
> tested by experts, with huge amounts of testing and fine-tuning on
> different systems and with different types of data. If you spend a
> similar effort, you might get similar results - but would you put that
> kind of effort into the C code?
>
> So while C is often the best choice when you really need the fastest
> code, that does not mean that writing in C makes your code fast or
> faster than alternatives.
>
>> I want to learn it well enough to understand or modify various open
>> source code.
>
> Open source code can be written in any one of dozens of languages -
> though C is quite common. Understanding the code is often a lot more
> than just understanding the language it is written in. Do you have
> particular projects that interest you?
The one I created recently is interesting. It reads in a .csv file and
summarizes and pivots the data (exactly like a pivot table in a
spreadsheet). Doing it answered the question "How is it done?" With
not much difficulty, it turns out.
The pivots in Excel 2003 (and the crosstab queries in Access 2003) are
so fast, though, that parts of them must have been written in assembler.
I did a xtab in Access and it pivoted 41K rows into 252 columns in 0.195
seconds.
>> I like that it's 'close to the metal'.
>>
>
> Ah, there you have a winner in C. It is as close to the metal as you
> can get without assembly.
>
>> Makes me a better programmer, too.
>
> Agreed. You would also be a better programmer if you learned other
> languages too - variety helps.
I know VB and VBA well, python pretty well, and am getting better in C.
> But a reasonable understanding of C is a
> good idea for a "general programmer".
I started 'programming' in 1985-86 (Lotus 1-2-3 macros as an adjunct to
my finance job). Got into IT work at IBM and spent 20 years off and on
doing freelance database work: mostly VB systems with Access, Oracle,
SQL Server, etc. high-level stuff. Some Java.
>> Currently I do it only as a hobby, but it would be nice to put on a
>> resume and be able to use C on the job if needed.
>>
>
> To program in C professionally, you need to take your learning more
> seriously than trial-and-error self learning.
A good course would be nice, but there's plenty to learn here and from
writing code and reading books.
> But that is fine for a
> hobby, and if you feel you are getting the hang of it and like the
> language, you can do a course to fill out the details and be ready to
> work in C.
I am getting the hang of C, though pointers and passing arrays are still
confusing.
>> Why do you use C?
>>
>
> Most of my work is small systems embedded programming, and C is simply
> the most appropriate language for the job. It used to be more assembly,
> and sometimes it is C++, but for the majority of this type of
> programming, C is the right choice. It gives you "close to the metal"
> programming while being far safer, and far more productive and portable
> than assembly. There are C toolchains for every microcontroller, but
> for many there are no other languages supported. Most existing code is
> in C, and most embedded programmers work in C, so that in itself means C
> is usually the best choice.
Embedded C seems interesting. I have the OReilly book by Barr
(Programming Embedded Systems in C and C++), but it will take more time
until I understand it all.
> And I like C programming on such systems.
>
> For PC programming, however, I mostly use Python - it gets the job done
> faster.
Sure.
I've written a good bit of python the last year. It's a very productive
environment.
Here's a short newsgroup stats program I wrote
(put in your credentials line 4)
---------------------------------------------------------
import sys as y,nntplib as t,datetime as d
s='news.eternal-september.org'
g=y.argv[1]
n=t.NNTP(s,119,'<user>','<password>')
r,a,b,e,gn=n.group(g)
def printStat(st,hd,rg):
p=[]
for itm in st:
r,d=n.xhdr(itm,'%s-%s'%rg)
for i,v in d:
if itm in ['From','Subject']:
v=v.replace(' ',' ');v=v.replace(' ',' ')
if itm=='Subject':
v=v[4:] if v[:3] in ['Re:','RE:'] else v
p.append(v)
z=[(i,p.count(i)) for i in set(p)]
z.sort(key=lambda s:(-s[1],s[0].lower()))
print('Posts %s %s'%(len(set(p)),hd))
print('-----
---------------------------------------------------------------------------------------')
for v in z: print '{:>4} {:<}'.format(v[1],v[0])
print
print('As of '+d.datetime.now().strftime("%I:%M%p %B %d, %Y")+'\n')
m=(int(e)-int(y.argv[3])+1,int(e))
printStat(['From'],'Posters',m)
printStat(['Subject'],'Subjects',m)
printStat(['User-Agent','X-Newsreader'],'Newsreaders',m)
printStat(['Organization'],'Organizations',m)
n.quit()
---------------------------------------------------------
usage: python filename.py newsgroup last N
example: python grpstats.py comp.lang.c last 500
python and SQLite is a good combo, too.
>>> By the way, C also has a sort function called qsort.
>>
>> I tried qsort at one point and didn't like it.
>> I'd rather:
>>
>> char groups2[g];
>> for (i = 0; i < g-1 ; i++)
>> {
>> for (j = i + 1; j < g; j++)
>> {
>> if (strcmp(groups[i], groups[j]) > 0)
>> {
>> strcpy(groups2, groups[i]);
>> strcpy(groups[i], groups[j]);
>> strcpy(groups[j], groups2);
>> }
>> }
>> }
>>
>
> You are mixing up your array sizes and your counts here.
>
> Apart from that, you have a bubble sort algorithm. That will run
> quickly for small samples, but be a lot slower for bigger ones.
I'll probably end up using qsort. I did some reading and it's
apparently very efficient.
I'd like to do a case-insensitive sort, so that will be a twist.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-22 11:03 +0100 |
| Message-ID | <87podw8hky.fsf@bsb.me.uk> |
| In reply to | #112819 |
DFS <nospam@dfs.com> writes:
> On 6/21/2017 7:35 AM, David Brown wrote:
>> On 21/06/17 03:37, DFS wrote:
<snip>
>>> Mainly I love the blazing execution speed of C.
>>>
>>
>> The speed of a program comes from many things. The algorithm used is
>> often more important than the language, and the speed of the tool's
>> libraries can be a big effect. Python excels at string handling,
>> searching and sorting - in some cases a few lines of Python code will
>> run faster than a C program for the job.
>
> python is slow at everything I've ever tried. A sed line will execute
> 4x faster than python (say to do some word replacements or swaps). C
> is 20x faster on avg I would say.
There are other speeds to consider. The speed with with a program can
be written in the first place is probably the most significant, but also
how quickly it can be adapted to new requirements, how fast it can be
understood by others, and so on.
> But python is easy to learn, and has a big bunch of libraries. And I
> love the python list comprehension.
>
> One line to count the unique characters in a string.
>
> msg = "Now is the time for all good men to come to the aid of their country"
> for t in sorted(set([(x,msg.count(x)) for x in msg])):
> print t[0],t[1]
If you like speed, you might want to write
for t in sorted([(x,msg.count(x)) for x in set(msg)]):
instead. (Personally, I'd write
for (letter, count) in sorted([(l, msg.count(l)) for l in set(msg)]):
print(letter, count)
because (a) Python3 and (b) I like destructuring binds.)
<snip>
>> ... Do you have
>> particular projects that interest you?
>
> The one I created recently is interesting. It reads in a .csv file
> and summarizes and pivots the data (exactly like a pivot table in a
> spreadsheet). Doing it answered the question "How is it done?" With
> not much difficulty, it turns out.
The code you posted probably has at least one bug. I am not entirely
sure where it is, but valgrind reports a problem and valgrind is very
rarely wrong. (I'm sorry I can't be more helpful but I investigated for
a while and then time got the better of me).
Also it if full of bugs waiting to happen since none of your string
operations are length limited and I'm not sure all the other array
accesses are properly checked either. I mention this not to be mean (as
I have been accused of being) but because it might be significant to a
discussion of time -- if you are writing a one-off "see how it could be
done" program, you would have finished long ago using a scripting
language, but if you want to write a re-usable, reliable utility program
you are no where near finished yet. Doing so would show you how much
time is needed to write robust C code.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web