Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #112706 > unrolled thread

Warning: assignment from incompatible pointer type

Started byDFS <nospam@dfs.com>
First post2017-06-20 12:48 -0400
Last post2017-06-21 15:10 +0100
Articles 20 on this page of 39 — 10 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#112706 — Warning: assignment from incompatible pointer type

FromDFS <nospam@dfs.com>
Date2017-06-20 12:48 -0400
SubjectWarning: 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]


#112708

Frombartc <bc@freeuk.com>
Date2017-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]


#112770

FromDFS <nospam@dfs.com>
Date2017-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]


#112774

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-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]


#112709

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-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]


#112743

FromDFS <nospam@dfs.com>
Date2017-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]


#112745

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-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]


#112748

Frombartc <bc@freeuk.com>
Date2017-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]


#112750

FromDFS <nospam@dfs.com>
Date2017-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]


#112711

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-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]


#112746

FromDFS <nospam@dfs.com>
Date2017-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]


#112718

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#112747

FromDFS <nospam@dfs.com>
Date2017-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]


#112749

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2017-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]


#112751

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#112752

FromDFS <nospam@dfs.com>
Date2017-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]


#112758

FromRichard Heathfield <rjh@cpax.org.uk>
Date2017-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]


#112759

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#112819

FromDFS <nospam@dfs.com>
Date2017-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]


#112825

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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