-3

Currently the code is reading the file and sort the records, as shown below,

#include"fileIO/file.h"

#define MAX_RECORD_SIZE 256 // Bad style


typedef struct{
  int age;
  char *lastName;
  char *firstName;
}Person;

 .....



int main(int argc, char *argv[]){

  FILE *pFile = fopen("file.txt", "r");

  ....
  callInsertionSort(getItemList(cache), getSize(getItemList(cache)), less);

}

where, file.txt is,

Age,LastName,FirstName
50,B,A
30,A,B
20,X,D
10,F,A
10,A,B
90,V,E
60,N,M

Execution:

$./sort.exe
Before sorting
Age,LastName,FirstName
  50  B  A
  30  A  B
  20  X  D
  10  F  A
  10  A  B
  90  V  E
  60  N  M
After sorting

Age,LastName,FirstName
  10  F  A
  10  A  B
  20  X  D
  30  A  B
  50  B  A
  60  N  M
  90  V  E

Question:

Without using fopen(), is there a way to get the shell to pass the contents of file.txt as command-line arguments, one argument per line in the file, (through argv by passing shell command (sort.exe) parameters)?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
overexchange
  • 15,768
  • 30
  • 152
  • 347
  • 2
    Use the filename from `argv` as the argument to `fopen()`, what's the problem? – Barmar Jan 17 '17 at 01:44
  • @Barmar I do not want to use `file` api to read `file.txt`. Can I pass command line paramters to read the content? – overexchange Jan 17 '17 at 01:46
  • Can you explain what you mean? What does "Can we read file.txt through argv" mean? – Retired Ninja Jan 17 '17 at 01:46
  • 3
    Maybe what you really want to do is read from standard input, and then use `program < file.txt` to redirect input to the file. – Barmar Jan 17 '17 at 01:47
  • See also the [comment](http://stackoverflow.com/questions/9242415/passing-arguments-to-main/9242493?noredirect=1#comment70571047_9242493) and the following ones. I believe the objective is to get the contents of the file passed to the command one line per argument. That isn't completely clear from the question, though. – Jonathan Leffler Jan 17 '17 at 01:47
  • @Barmar No, I do not want to `getchar()` the content. – overexchange Jan 17 '17 at 01:48
  • You will have to use some library function to read the data. `argv` is just an array of command line argument strings. – Retired Ninja Jan 17 '17 at 01:49

2 Answers2

4

You can run the program as:

IFS=$'\n'
./sort.exe $(cat file.txt)

Each line of the file will then be an argument to the program (setting IFS to just newline prevents spaces in the file from being argument delimiters).

Then the program can loop over argv (except for argv[0], which contains the program name) to get all the lines to sort.

Note that there's a limit on the size of the arguments, so this method is not very scalable. Reading from the file is generally preferred.

FYI, $(cat file.txt) can also be written as $(< file.txt)

Barmar
  • 741,623
  • 53
  • 500
  • 612
2

If the objective is to pass each line of the file as a separate command line argument to the sort.exe program, then you will need Bash (which is in the tags) and you can use:

IFS=$'\n'; sort.exe $(cat file)

To demonstrate, take an alternative command, printf, and a data file like this, using to represent a blank:

verbiage
spaced⧫out
⧫leading⧫and⧫trailing⧫
⧫⧫multiple⧫⧫spaces⧫⧫everywhere⧫⧫

Running the command yields:

$ ( IFS=$'\n'; printf '[%s]\n' $(cat file) )
[verbiage]
[spaced out]
[ leading and trailing ]
[  multiple  spaces  everywhere  ]
$

This uses the outer ( … ) to run the command in a sub-shell so that my interactive IFS is not messed up. They're unnecessary in some other contexts.

Note that there's an upper-bound on how long the command line arguments (plus environment variables) can be — it is sometimes as much as 256 KiB, and seldom larger. This means you can only afford to do this with small enough files. In most circumstances, you'd be better off following the Unix (POSIX) sort command and reading the data direct from the filename specified as an argument to the sort command.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278