Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

dougphd

macrumors member
Original poster
Apr 28, 2016
70
0
here's the code

Code:
void main
char num[10], cmd[75];
int files;
char *end;
strcpy(cmd, "ls ");
strcat(cmd,scan_data_home);
strcat(cmd," | wc -l");
fp = popen(cmd, "r");
while (fgets(num, sizeof(num)-1, fp) != NULL)
      printf("%s\n",num);
files = (int) strtol(num, &end, 10);
printf("%d\n", files);
printf("1 %c\n", num[0]);
printf("2 %c\n", num[1]);
printf("3 %c\n", num[2]);
printf("4 %c\n", num[3]);
printf("5 %c\n", num[4]);
printf("6 %c\n", num[5]);
printf("7 %c\n", num[6]);
printf("8 %c\n", num[7]);
 /[code]


here's the output. I tried to duplicate the actual line spacing
[code]
[B]              3739[/B]



0
[B]1 [/B]

[B]2 
3  
4  
5 3
6 7
7 3
8 9[/B]
/[code]

What gives and how to I convert the string to an int.
 
I tested this on my Linux machine and there it works. Note that your code is full of potential buffer overflows and magic numbers. Maybe the data path is longer than you expected?

Do you really, really need to do all your work in C?
 
Yes. And in this case, I have been asked to use it specifically for it's speed. As far as the overflows and magic numbers, this code snippet is merely to demonstrate an example of 3-D modeling. Better comes later, although I am not above improving this. Thanks for your help. The work is done on a MAC. Do you have any suggestions as what to do.

If you use a language with a run time complier, how do to avoid crashing after the code has run for three hours because of a typo?
[doublepost=1479299293][/doublepost]Works on my machine too. Must be something in the input which is read from a csv file.

Code:
char test1[10], test2[10];
strcpy(test1,"3797");
files = (int) strtol(test1, &end, 10);
printf("%d\n", files);
strcpy(test2,"00003797");
files = (int) strtol(test2, &end, 10);
printf("%d\n", files);
strcpy(test3,"    3797");
files = (int) strtol(test3, &end, 10);
printf("%d\n", files);
/[code]
 
Again, you posted a mass of code that is full of syntax errors and missing what is needed to run the code to see why it doesn't work.

I also noticed that you almost always screw up your code tags. You enter them as /[code_tag] instead of [/code_tag]

This tells me two things:

1 - You don't pay attention to the message you entered which makes me thing you don't pay attention to the code you enter
2 - You don't bother to look at your posted message to see if it's clear to others, you would instantly notice the formatting is off

If you use a language with a run time complier, how do to avoid crashing after the code has run for three hours because of a typo?
You can still test your code. You'd be amazed at how many web sites run on Ruby, Python, etc which are 'interpreted' languages (not 'run-time compiled'). Most forums run PHP which is interpreted!

[doublepost=1479301353][/doublepost]
Code:
#include <stdio.h>
#include <string.h>

void main (void)
{
  char num[10] = "iiiiiiiii\n";
  char cmd[75];
  int files;
  FILE *fp;
  char *scan_data_home = "~";
  char *end;

  strcpy (cmd, "ls ");
  strcat (cmd, scan_data_home);
  strcat (cmd, " | wc -l");
  fp = popen (cmd, "r");

  while (fgets (num, sizeof (num) - 1, fp) != NULL) {
      printf ("\nValue of the char array 'num': %s\n", num);
  }

  files = (int) strtol (num, &end, 10);

  printf ("Value of 'int files': %d\n", files);
  printf ("Each value of the num char array:\n");
  printf ("num[0] %x\n", num[0]);
  printf ("num[1] %x\n", num[1]);
  printf ("num[2] %x\n", num[2]);
  printf ("num[3] %x\n", num[3]);
  printf ("num[4] %x\n", num[4]);
  printf ("num[5] %x\n", num[5]);
  printf ("num[6] %x\n", num[6]);
  printf ("num[7] %x\n", num[7]);
}

Code:
$ ./a.out

While loop output: 10

10
num[0] 31
num[1] 30
num[2] a
num[3] 0
num[4] 69
num[5] 69
num[6] 69
num[7] 69

If you look at an ASCII chart you'll see each value (in hex) of the num array

better_ascii_table.jpg


So you see the string that contains '10' ends up really holding

'1', '0', '\n', NULL, 'i', 'i', 'i', 'i'

The i's are left there so you can see they aren't overwritten (I set char num[] to 'iiiiiiii' at the beginning of the code. But C sees the NULL it doesn't care and quits processing the array as a string.
 
Last edited:
If you use a language with a run time complier, how do to avoid crashing after the code has run for three hours because of a typo?

How do you avoid crashing when your program is run on a data directory several levels deep, leading to longer path names than you expected?

Note that nowhere I said you should use a run time (interpreted) language, as this is exactly my beef with these. But there is a middle ground too. I highly doubt that the performance bottleneck in your app is in counting the number of files in a directory. Whether this takes 99ms or 101ms won't make the difference.

In fact, in most cases the actual processing is performed in libraries which were written in a compiled-to-native language (probably C or C++) and your "run time language" is just used as glue. This lets you focus on the important stuff.
 
Again, you posted a mass of code that is full of syntax errors and missing what is needed to run the code to see why it doesn't work.

I also noticed that you almost always screw up your code tags. You enter them as /[code_tag] instead of [/code_tag]

This tells me two things:

1 - You don't pay attention to the message you entered which makes me thing you don't pay attention to the code you enter
2 - You don't bother to look at your posted message to see if it's clear to others, you would instantly notice the formatting is off


You can still test your code. You'd be amazed at how many web sites run on Ruby, Python, etc which are 'interpreted' languages (not 'run-time compiled')
yes i have trouble paying attention to detail and maybe a bit
Again, you posted a mass of code that is full of syntax errors and missing what is needed to run the code to see why it doesn't work.

I also noticed that you almost always screw up your code tags. You enter them as /[code_tag] instead of [/code_tag]

This tells me two things:

1 - You don't pay attention to the message you entered which makes me thing you don't pay attention to the code you enter
2 - You don't bother to look at your posted message to see if it's clear to others, you would instantly notice the formatting is off


You can still test your code. You'd be amazed at how many web sites run on Ruby, Python, etc which are 'interpreted' languages (not 'run-time compiled'). Most forums runs PHP which is interpreted!

[doublepost=1479301353][/doublepost]
Code:
#include <stdio.h>
#include <string.h>

void main (void)
{
  char num[10] = "iiiiiiiii\n";
  char cmd[75];
  int files;
  FILE *fp;
  char *scan_data_home = "~";
  char *end;

  strcpy (cmd, "ls ");
  strcat (cmd, scan_data_home);
  strcat (cmd, " | wc -l");
  fp = popen (cmd, "r");

  while (fgets (num, sizeof (num) - 1, fp) != NULL) {
      printf ("\nValue of the char array 'num': %s\n", num);
  }

  files = (int) strtol (num, &end, 10);

  printf ("Value of 'int files': %d\n", files);
  printf ("Each value of the num char array:\n");
  printf ("num[0] %x\n", num[0]);
  printf ("num[1] %x\n", num[1]);
  printf ("num[2] %x\n", num[2]);
  printf ("num[3] %x\n", num[3]);
  printf ("num[4] %x\n", num[4]);
  printf ("num[5] %x\n", num[5]);
  printf ("num[6] %x\n", num[6]);
  printf ("num[7] %x\n", num[7]);
}

Code:
$ ./a.out

While loop output: 10

10
num[0] 31
num[1] 30
num[2] a
num[3] 0
num[4] 69
num[5] 69
num[6] 69
num[7] 69

If you look at an ASCII chart you'll see each value (in hex) of the num array

better_ascii_table.jpg


So you see the string that contains '10' ends up really holding

'1', '0', '\n', NULL, 'i', 'i', 'i', 'i'

The i's are left there so you can see they aren't overwritten (I set char num[] to 'iiiiiiii' at the beginning of the code. But C sees the NULL it doesn't care and quits processing the array as a string.
yes i have trouble paying attention to detail and may be a bit dyslexic. sorry for not previewing my post this morning i was in a rush.
How do you avoid crashing when your program is run on a data directory several levels deep, leading to longer path names than you expected?

Note that nowhere I said you should use a run time (interpreted) language, as this is exactly my beef with these. But there is a middle ground too. I highly doubt that the performance bottleneck in your app is in counting the number of files in a directory. Whether this takes 99ms or 101ms won't make the difference.

In fact, in most cases the actual processing is performed in libraries which were written in a compiled-to-native language (probably C or C++) and your "run time language" is just used as glue. This lets you focus on the important stuff.
[doublepost=1479305784][/doublepost]
How do you avoid crashing when your program is run on a data directory several levels deep, leading to longer path names than you expected?

Note that nowhere I said you should use a run time (interpreted) language, as this is exactly my beef with these. But there is a middle ground too. I highly doubt that the performance bottleneck in your app is in counting the number of files in a directory. Whether this takes 99ms or 101ms won't make the difference.

In fact, in most cases the actual processing is performed in libraries which were written in a compiled-to-native language (probably C or C++) and your "run time language" is just used as glue. This lets you focus on the important stuff.
thanks for that clarification. yes there will be lots of data reduction and process.
 
You'd be better off just using C++ and an ifstream object, even if speed is an issue.

And as speed is almost never an issue when parsing a file, I say use Python and stop reinventing the wheel.
 
yes i have trouble paying attention to detail. i may be a bit dyslexic too. sorry not to have checked this this morning i was in a rush. i will check the rest of your response when i have more time.
i've worked languages with runtime compilers and i hate them for the reason stated above. i have to do real time conversion of streams of data to real time images. my employer has already tried matlab and wants it done in c. if he wanted it in ruby somebody else would be doing it. finally i am never hired for my programming abilities. i'm hired because i can develop algorithms. a big difference. however this time i have put a big c book on my desk so i can improve and not bother the forum so much. your help is always appreciated

Anyway the answer to my original question is that when matlab converts my .mat file to a csv file, it's doing strange things.
[doublepost=1479317379][/doublepost]What are you curious about? the modeling. Take two sets of data taken at the same time but at different points in time.
Z(t) and X and Y (T)
Extract certain spatial points from the first file. Line them up wth the time from the XY file and plot.
[doublepost=1479318047][/doublepost]Not matlab. that was silly.
The problem is the system call with popen.
 
Last edited:
Here's the solution

Code:
while (fgets(num, 10, fp) != NULL)
printf("%s\n",num);
num = strrchr(num,' ');
files = (int) strtol(num, &end, 10);
 
Here's the solution

Code:
while (fgets(num, 10, fp) != NULL)
printf("%s\n",num);
num = strrchr(num,' ');
files = (int) strtol(num, &end, 10);
Here's another solution (no other changes to original):
Code:
char num[ 30 ], cmd[75];
Explain the result.
 
You won't learn to program in C by creating your own examples that are beyond your ability. The real way to do it is to read a learn to program in C book and do the examples. This is probably true in other languages as well. I learned by reading "A Book on C" by Kelly and Pohl.
 
Thanks but it's worked so far.
[doublepost=1479397322][/doublepost]
Here's another solution (no other changes to original):
Code:
char num[ 30 ], cmd[75];
Explain the result.
You want me to explain it? Do I get a hint? BTW 10 didn't work.
 
You want me to explain it? Do I get a hint? BTW 10 didn't work.
Yes.

To understand exactly what the error in the original code is, you need to understand exactly why the single change I posted causes it to work. If you understand the reason, then an explanation will be simple and brief. If not, it won't.

Here's a hint.

Start with the original code (i.e. num[10]). Add the line shown below, in the place shown:
Code:
printf( "strtol will parse the string (%s)  with length %d\n", num, (int) strlen(num) );

files = (int) strtol(num, &end, 10);
Explain the result.

If you can't explain the result with num[10], try it with num[30], or num[5] (yes, five; not a typo), and explain those results. You need a clear and accurate mental image of what's happening.
 
Last edited:
Yes.

To understand exactly what the error in the original code is, you need to understand exactly why the single change I posted causes it to work. If you understand the reason, then an explanation will be simple and brief. If not, it won't.

Here's a hint.

Start with the original code (i.e. num[10]). Add the line shown below, in the place shown:
Code:
printf( "strtol will parse the string (%s)  with length %d\n", num, (int) strlen(num) );

files = (int) strtol(num, &end, 10);
Explain the result.

If you can't explain the result with num[10], try it with num[30], or num[5] (yes, five; not a typo), and explain those results. You need a clear and accurate mental image of what's happening.
[doublepost=1479402405][/doublepost]num[5]
ls /Users/douglasbrenner/Documents/Gaurav/a_scan_data/ | wc -l
strtol will parse the string ( ) with length 3
strtol will parse the string ( 37) with length 3
strtol will parse the string (39
) with length 3
3

num[10]
ls /Users/douglasbrenner/Documents/Gaurav/a_scan_data/ | wc -l
strtol will parse the string ( 3739) with length 8
strtol will parse the string (
) with length 1
0

num[30]
ls /Users/douglasbrenner/Documents/Gaurav/a_scan_data/ | wc -l
strtol will parse the string ( 3739
) with length 9
3739

First, it tells me what I already knew: that the system call puts in 4 leading zeros.
Not sure why 10 won't work. 11 works.

Can we take this discussion of the board. Might be easier.
 
...
First, it tells me what I already knew: that the system call puts in 4 leading zeros.
Not sure why 10 won't work. 11 works.

Can we take this discussion of the board. Might be easier.
You may already have known this, but it hasn't lead to an understanding of what happens.

I asked you to explain the output. That is, why does 30 work?

You're looking at the evidence (program output), but not seeing what it says.

The system call isn't putting in any zeros. If you look more carefully at the data (hint: %x), it won't be zeros. This isn't directly related to the reason for failure, it's just a mistaken detail.

If you understand why 11 works, then you should be able to work out why 10 doesn't work. If not, go smaller. For example, try 9. What happens? Try 8. Explain what happens as you decrease the size of num.

Here's a command-line whose output shows the data:
Code:
ls /Users/douglasbrenner/Documents/Gaurav/a_scan_data/ | wc -l | hexdump -C
Look at the data. Count it.

Look at your original code. How are you reading the data? Exactly what values are being passed in?


Finally, the printf I asked you to add should run exactly once. If it's in a loop, it's in the wrong place. That is, you should ADD the one printf given, outside the loop.

If you're going to change the printf in the loop, make it tell you more, clearly:
Code:
while (fgets(num, sizeof(num)-1, fp) != NULL)
     printf( "fgets got (%s), len %d\n", num, (int) strlen(num) );
 
Last edited:
I want to point out to the O.P. that if all you want is the number of files in a directory, then you should be using the readdir() API to do that. It is the POSIX API that should be used to examine directories from C. In general, if you think you need to use system() to get some information about something on your computer, then that means there is some underlying API to get it. You should be using that API directly and not going through all this nonsense. It will be faster and less error-prone.
 
Last edited:
  • Like
Reactions: Madd the Sane
You may already have known this, but it hasn't lead to an understanding of what happens.

I asked you to explain the output. That is, why does 30 work?

You're looking at the evidence (program output), but not seeing what it says.

The system call isn't putting in any zeros. If you look more carefully at the data (hint: %x), it won't be zeros. This isn't directly related to the reason for failure, it's just a mistaken detail.

If you understand why 11 works, then you should be able to work out why 10 doesn't work. If not, go smaller. For example, try 9. What happens? Try 8. Explain what happens as you decrease the size of num.

Here's a command-line whose output shows the data:
Code:
ls /Users/douglasbrenner/Documents/Gaurav/a_scan_data/ | wc -l | hexdump -C
Look at the data. Count it.

Look at your original code. How are you reading the data? Exactly what values are being passed in?


Finally, the printf I asked you to add should run exactly once. If it's in a loop, it's in the wrong place. That is, you should ADD the one printf given, outside the loop.

If you're going to change the printf in the loop, make it tell you more, clearly:
Code:
while (fgets(num, sizeof(num)-1, fp) != NULL)
     printf( "fgets got (%s), len %d\n", num, (int) strlen(num) );
I meant spaces. I did a hex dump earlier
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.