LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-15-2006, 10:07 PM   #1
smoothdogg00
Member
 
Registered: Feb 2006
Location: Maine
Distribution: Ubuntu
Posts: 44

Rep: Reputation: 15
Question Could someone check my stat struct code? (C)


Variables and function call:
Code:
char * filelist[n];

sortByTime(filelist);
My function:
Code:
int sortByTime(char * arr[])
{
  int i, j;
  char * temp;
  for(i = (sizeof(arr)/sizeof(char *)); i >= 1; i--)
    {
      for(j = 1; j < (i - 1); j++)
	{
	  stat(&arr[j], &arr[j + 1]);
	  if(&arr[j].st_mtime > &arr[j + 1].st_mtime)
	    {
	      strcpy(temp, arr[j]);
	      strcpy(arr[j], arr[j + 1]);
	      strcpy(arr[j + 1], temp);
	    }
	}
    }
}
The problem is with my stat structure and accessing the st_mtime. (But if you see any other problems feel free to let me know :-))
 
Old 03-15-2006, 11:02 PM   #2
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
Code:
gcc -c -Wall sometest.c
sometest.c: In function `sortByTime':
sometest.c:23: warning: passing arg 1 of `stat' from incompatible pointer type
sometest.c:23: warning: passing arg 2 of `stat' from incompatible pointer type
sometest.c:24: error: request for member `st_mtim' in something not a structure
or union
sometest.c:24: error: request for member `st_mtim' in something not a structure
or union
line23:
The first argument of stat must be a pointer to a string, the second one must be a pointer to a struct stat.
line24:
arr is not of type struct stat, and for that reason does not contain a member st_mtime

It seems that you don't have any idea what your doing. Benefit of the doubt with regards to 'homework' question.

Code:
int sortByTime(char * arr[])
{
  struct stat sb1,sb2;
  int i, j;
  char * temp;
  for(i = (sizeof(arr)/sizeof(char *)); i >= 1; i--)
    {
      for(j = 1; j < (i - 1); j++)
        {
          stat(arr[j], &sb1);
          stat(arr[j+1], &sb2);
          if(sb1.st_mtime > sb2.st_mtime)
            {
              strcpy(temp, arr[j]);
              strcpy(arr[j], arr[j + 1]);
              strcpy(arr[j + 1], temp);
            }
        }
    }
    return 0;
}
With the correct include files, this compiles without errors. I did not check if it works.

Last edited by Wim Sturkenboom; 03-15-2006 at 11:08 PM.
 
Old 03-15-2006, 11:37 PM   #3
smoothdogg00
Member
 
Registered: Feb 2006
Location: Maine
Distribution: Ubuntu
Posts: 44

Original Poster
Rep: Reputation: 15
Question

Ok, that worked great, thanks a lot.

Now, for the next question (probably even easier):

Code:
(sizeof(arr)/sizeof(char *))
This is giving me trouble in the above code.

I can access items within arr with the following:
Code:
printf("%s", arr[10])
So I know there is more than one element in the array. However, first code sample results in 1, meaning that the size of the array is 4 and the size of char* is 4 (normal). Why would it say the array size is 4, when I can access things up to [50]?

And "yes", it is true that I have almost no idea what I am doing in C. I am being forced to learn it and program with it, but it is not being taught to me.

Last edited by smoothdogg00; 03-15-2006 at 11:39 PM.
 
Old 03-16-2006, 03:58 AM   #4
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
Code:
int sortByTime(char * arr[])
arr[] is an array (of pointers to char) so arr is a pointer
For that reason it has a size of 4 (on 32bit systems), In your situation, you have to pass the number of elements as a second argument.
 
Old 03-16-2006, 11:04 AM   #5
smoothdogg00
Member
 
Registered: Feb 2006
Location: Maine
Distribution: Ubuntu
Posts: 44

Original Poster
Rep: Reputation: 15
I'm actually changing to a qsort now, and I'm having problems.

My variables:
Code:
char * filelist[n];
int files;
My call to qsort:
Code:
qsort((void*)filelist, files, sizeof(char *), compare());
My comparator function:
Code:
int compare(const void * s1, const void * s2)
{
  char * string1 = (char *)s1;
  char * string2 = (char *)s2;

  struct stat struct1, struct2;
  int t1, t2;

  stat(string1, &struct1);
  stat(string2, &struct2);
  t1 = struct1.st_mtime;
  t2 = struct2.st_mtime;

  if(t1 > t2)
    return -1;
  else if(t1 < t2)
    return 1;
  else
    return 0;
}
My Error:
Code:
Segmentation fault (core dumped)

Last edited by smoothdogg00; 03-16-2006 at 11:06 AM.
 
Old 03-17-2006, 02:04 AM   #6
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
When I compiled, I got a warning on the line where you call qsort. It disappeared when changed it to
Code:
qsort((void*)filelist, files, sizeof(char *), compare);
The code that you showed did not cause segfaults on my system. It however does not sort correctly due to pointer problems. This might cause the segfault or it might not (in which case you have to look in code that you did not post).

The sort-problem is in your compare routine. Use of a debugger or printf statements will help.

debugging using printf
----------------------
First add a simple printf as the first line after the variable declaration in the compare function.
Code:
printf("entering compare\n");
return 0;
Using the return, we force to skip the rest of the compare function. If you don't get a segfault, you're problem is (very likely) in the compare function.
Next add the following code before the new return
Code:
printf("%s | %s\n", (char*)s1,(char*)s2);
This might cause a segfault or print garbage which is an indication that there's a pointer problem.
Next you can start printing pointers. First change the %s in the above printf by %p
Code:
printf("%p | %p\n", (char*)s1,(char*)s2);
Also add a loop before you call qsort and print out the content of filelist. Mine code looked like
Code:
for(i=0;i<no_of_words;i++)
{
  printf("%2d: %p %s\n",i+1,words[i],words[i]);
}
You will now see that the pointers don't have any relation while you expect to see the values printed in the loop to show in the compare as well (s1 and s2). There also should not be a segfault (to my knowkedge)

explanation
-----------
Your compare routine takes two pointers to a void; however, you're passing an array of pointers as the first argument of qsort and for that reason your arguments in the compare-function are pointers to a pointer (and not pointers to void).
Some small changes solve it
Code:
char ** string1 = (char **)s1;
char ** string2 = (char **)s2;
and
Code:
stat(*string1, &struct1);
stat(*string2, &struct2);
PS I did not use filelist and files, but words and no_of_words

Last edited by Wim Sturkenboom; 03-17-2006 at 02:37 AM. Reason: added PS
 
Old 03-17-2006, 12:23 PM   #7
smoothdogg00
Member
 
Registered: Feb 2006
Location: Maine
Distribution: Ubuntu
Posts: 44

Original Poster
Rep: Reputation: 15
For some reason when I use:
Code:
qsort((void*)filelist, files, sizeof(char *), compare);
I get a compilation error:
Code:
error: 'compare' undeclared (first use in this function)
Any idea what the problem might be?

It is declared as:
Code:
int compare(const void * s1, const void * s2)
 
Old 03-20-2006, 12:47 AM   #8
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
Sorry, can't explain why.
 
Old 03-20-2006, 07:09 AM   #9
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
The compare function is a function that you will need to declare, that will determine how you compare two values. If the first value is to be considerd greater that then second then it should return a positive number. So a simple implementation for integers might just be

Code:
int compare(const void * s1, const void * s2)
{
   return (int)(*s1) - (int)(*s2);
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
cant send a whole struct with sockets (c code) alaios Programming 9 04-12-2020 09:52 AM
g++ and wrong struct member addresses / struct size misreporting sonajiso Linux - General 5 05-22-2004 10:16 PM
switch statement converting struct char to struct int oceaneyes2 Programming 2 12-10-2003 04:30 PM
using struct type X as pointer in struct X. worldmagic Programming 1 10-28-2003 02:06 PM
Accessing a struct inside struct cxel91a Programming 1 09-17-2003 04:24 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:00 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration