I want to run a command line argument to interpret a username, name, email, and home directory. I got the username part right but the rest is out of place. I don't know if I am placing the strtok function in the right place and each time I compile, it errors out "the variable is unused.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s <username>\n", argv[0]);
return 1;
}
char *username = argv[1];
FILE *passwd = fopen("/etc/passwd", "r");
if (!passwd) {
perror("fopen");
return 1;
}
char *line = NULL;
size_t max_length = 0;
ssize_t ret_val = 0;
char line_copy[1000];
while ((ret_val = getline(&line, &max_length, passwd)) > 0) {
strncpy(line_copy, line, 999);
char *user = strtok(line_copy, ":");
if (strcmp(user, username) == 0) {
char *name = strtok(NULL, ":");
char *email = strtok(NULL, ":");
char *home_dir = strtok(NULL, ":");
printf("user: %s\n", user);
printf("name: %s\n", name);
printf("email: %s\n", email);
printf("home directory: %s\n", home_dir);
}
}
fclose(passwd);
passwd = NULL;
return 0;
}
At least on Linux /etc/passwd contains the colon separated fields login name, password, user id, group id, user name, home directory and shell. You have call strtok() for the fields you want to skip, and there is no email field:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s <username>\n", argv[0]);
return 1;
}
char *username = argv[1];
FILE *passwd = fopen("/etc/passwd", "r");
if (!passwd) {
perror("fopen");
return 1;
}
char *line = NULL;
size_t max_length = 0;
ssize_t ret_val;
while ((ret_val = getline(&line, &max_length, passwd)) > 0) {
if (strcmp(username, strtok(line, ":")) == 0) {
strtok(NULL, ":"); // password
strtok(NULL, ":"); // uid
strtok(NULL, ":"); // gid
char *name = strtok(NULL, ":");
char *home_dir = strtok(NULL, ":");
printf("user: %s\n", username);
printf("name: %s\n", name);
printf("home directory: %s\n", home_dir);
}
return 0;
}
fclose(passwd);
return 1;
}
Consider using getpwnam() instead:
#define _GNU_SOURCE
#include <pwd.h>
#include <stdio.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s <username>\n", argv[0]);
return 1;
}
struct passwd *pw = getpwnam(argv[1]);
if(!pw)
return 1;
printf("user: %s\n", pw->pw_name);
printf("name: %s\n", pw->pw_gecos);
printf("home directory: %s\n", pw->pw_dir);
}
Related
I have a bit of code and I need to split the words in the filename and store them separately.
Example:
Input -> filename ( e.g. /Users/user/Documents/uni)
Storage in variable/array as separate words ( not sure how):
char array/struct array = Users user Documents uni
How can I achieve the above example of storing words with C?
Here is my code:
int main(int argc, char *argv[])
{
char filename[255];
for (int i = 0; i < argc; i++)
{
strcpy(&filename[i], argv[i]);
}
}
Thanks in advance
Would you please try the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char filename[BUFSIZ]; // pathname
int i;
int n = 0; // number of words
char **ary = NULL; // array of strings
char *tok; // pointer to each token
if (argc != 2) { // verify aruguments
fprintf(stderr, "usage: %s pathname\n", argv[0]);
exit(1);
}
strncpy(filename, argv[1], BUFSIZ);
for (tok = strtok(filename, "/"); tok != NULL; tok = strtok(NULL, "/")) {
if (NULL == (ary = realloc(ary, (n + 1) * sizeof(*ary)))) {
// enlarge array of strings
perror("realloc");
exit(1);
}
if (NULL == (ary[n] = malloc(strlen(tok) + 1))) {
// allocate memory for the word
perror("malloc");
exit(1);
}
strncpy(ary[n], tok, strlen(tok) + 1);
// copy the token to the array
n++;
}
// see the results
for (i = 0; i < n; i++) {
printf("[%d] %s\n", i, ary[i]);
}
// free the allocated memory
for (i = 0; i < n; i++) {
free(ary[i]);
}
free(ary);
return 0;
}
If you compile the code to the executable a.out, the outout will look like:
$ ./a.out /Users/user/Documents/uni
[0] Users
[1] user
[2] Documents
[3] uni
I have managed to achieve the desired outcome with this piece of code:
int main(int argc, char *argv[])
{
char word[255];
const char s[2] = "/";
char *token;
if( argc == 2 ) {
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 ) {
printf("Too many arguments supplied.\n");
}
strcpy(word, argv[0]);
token = strtok(word, s);
while( token != NULL ) {
printf( " %s\n", token );
token = strtok(NULL, s);
}
}
I am currently reading a text file that is below:
New York,4:20,3:03
Kansas City,12:03,3:00
North Bay,16:00,0:20
Kapuskasing,10:00,4:02
Thunder Bay,0:32,0:31
I have the city names being fprintf to a new .txt file which works fine, however I am trying to take the times and print them to a binary file and am stuck as to where I am having an issue. Any help would be appreciated.I need to store the times as 04, 20 for "New York" in a 2 byte value and having issues parsing to have this specifically.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable: 4996)
// a function to remove the trailing carraige return
void clearTrailingCarraigeReturn(char* buffer);
/* == FUNCTION PROTOTYPES == */
/* == CONSTANTS == */
// MAIN
typedef struct
{
char cityName[20];
short flightTime;
short layoverTime;
} Flight;
Flight parseFlight(char* line) {
char delimiter[2] = ",";
Flight flight;
char* token = strtok(line, delimiter);
int i = 0;
while (token != NULL)
{
if (i == 0)
{
strcpy(flight.cityName, token);
}
if (i == 1)
{
flight.flightTime = atoi(token);
}
if (i == 2)
{
flight.layoverTime = atoi(token);
}
token = strtok(NULL, delimiter);
i++;
}
return flight;
}
int main(int argc, char* argv[])
{
FILE *fpIn, *fpOut, *fbOut;
char line[80];
Flight flight;
fpIn = fopen(argv[1], "r");
fpOut = fopen("theCities.txt", "w+");
fbOut = fopen("theTimes.dat", "wb+");
while (fgets(line, 1024, fpIn) > 0)
{
clearTrailingCarraigeReturn(line);
printf(" >>> read record [%s]\n", line);
flight = parseFlight(line);
fprintf(fpOut, "%s\n", flight.cityName);
fwrite(&flight.flightTime, sizeof(short), 1, fbOut);
fwrite(&flight.layoverTime, sizeof(short), 1, fbOut);
}
fclose(fpIn);
fclose(fpOut);
fclose(fbOut);
}
// This function locates any carraige return that exists in a record
// and removes it ...
void clearTrailingCarraigeReturn(char* buffer)
{
char* whereCR = strchr(buffer, '\n');
if (whereCR != NULL)
{
*whereCR = '\0';
}
}
Perhaps something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Time_s
{
unsigned char hours;
unsigned char minutes;
} Time_t;
typedef struct Flight_s
{
char cityName[20];
Time_t flightTime;
Time_t layoverTime;
} Flight_t;
// a function to remove the trailing carraige return
void clearTrailingCarraigeReturn(char *buffer)
{
int more;
do {
size_t index;
index = strlen(buffer);
if(!index)
break;
--index;
switch(buffer[index])
{
case '\n':
case '\r':
buffer[index] = '\0';
more = 1;
break;
default:
more = 0;
break;
}
} while(more);
return;
}
int ParseTime(char *timeStr, Time_t *time)
{
int rCode=0;
char *next;
time->hours = (unsigned char)strtoul(timeStr, &next, 10);
if(':' == *next)
{
++next;
time->minutes = (unsigned char)strtoul(next, NULL, 10);
}
return(rCode);
}
Flight_t parseFlight(char* line)
{
char delimiter[2] = ",";
Flight_t flight;
char *token = strtok(line, delimiter);
int i = 0;
while(token)
{
switch(i)
{
case 0:
strcpy(flight.cityName, token);
break;
case 1:
ParseTime(token, &flight.flightTime);
break;
case 2:
ParseTime(token, &flight.layoverTime);
break;
}
token = strtok(NULL, delimiter);
i++;
}
return(flight);
}
int main(int argc, char* argv[])
{
int rCode=0;
FILE *fpIn=NULL, *fpOut=NULL, *fbOut=NULL;
char line[80+1];
Flight_t flight;
if(argc < 2)
{
fprintf(stderr, "ERROR: argc < 2\n");
goto CLEANUP;
}
fpIn = fopen(argv[1], "r");
if(!fpIn)
{
fprintf(stderr, "ERROR: fopen(\"%s\",\"r\")\n", argv[1]);
goto CLEANUP;
}
fpOut = fopen("theCities.txt", "w+");
if(!fpOut)
{
fprintf(stderr, "ERROR: fopen(\"theCities.txt\",\"w+\")\n");
goto CLEANUP;
}
fbOut = fopen("theTimes.dat", "wb+");
if(!fbOut)
{
fprintf(stderr, "ERROR: fopen(\"theTimes.dat\",\"wb+\")\n");
goto CLEANUP;
}
while(fgets(line, sizeof(line), fpIn) > 0)
{
clearTrailingCarraigeReturn(line);
flight = parseFlight(line);
printf("%s,%02hhu:%02hhu,%02hhu:%02hhu\n",
flight.cityName,
flight.flightTime.hours, flight.flightTime.minutes,
flight.layoverTime.hours, flight.layoverTime.minutes
);
fprintf(fpOut, "%s\n", flight.cityName);
fwrite(&flight.flightTime, sizeof(Time_t), 1, fbOut);
fwrite(&flight.layoverTime, sizeof(Time_t), 1, fbOut);
}
CLEANUP:
if(fpIn)
fclose(fpIn);
if(fpOut)
fclose(fpOut);
if(fbOut)
fclose(fbOut);
return(rCode);
}
What is the best way to read name and its value from a configuration file in c programming?
Sample configuration file:
NAME=xxxx
AGE=44
DOB=mmddyyyy
WORK=zzzz
This is the code which I am using. It is working. But I would like to know if there is a better way.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int getValue(char *line, char* name, char value[])
{
char* pch = NULL;
char* token = NULL;
pch = strstr(line, name);
if(pch)
{
token = strtok(pch, "=");
while (token != NULL)
{
pch = token;
token = strtok(NULL, "=");
}
pch[strcspn ( pch, "\n" )] = '\0';
strcpy(value,pch);
return 1;
}
return 0;
}
int main()
{
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
char value[100];
int ret = 0;
fp = fopen("test.txt", "r");
if (fp == NULL)
{
printf ("Cannot open file \n");
return -1;
}
while ((read = getline(&line, &len, fp)) != -1)
{
ret = getValue(line,"NAME",value);
if (ret)
{
printf("NAME is %s\n", value);
}
ret = getValue(line,"AGE",value);
if (ret)
{
printf("AGE is %s\n", value);
}
}
free(line);
fclose(fp);
return 0;
}
I would be also happy to hear if there is any issue with this code.
There are several issues
When the file is like below, your parsing is incorrect. it be found as long as there is this string on the line, regardless of whether it is on the value or part of the key.
NAMEX=xxxx
AGEX=44
DOB=mmddyyyyAGE
WORK=zzzzAGE
Use strtok line content will be changed. In fact, when you call getValue for the second time, the content of line is different from the file.
AGE=NAMEzzzz=1=2
From the performance, you can directly use line the substring, no need to strcpy out
It is recommended to parse the key and value first, then compare the key you are looking for multiple times. the code below is for reference only
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *trim(char *str)
{
char *start = str;
char *end = str + strlen(str);
while(*start && isspace(*start))
start++;
while(end > start && isspace(*(end - 1)))
end--;
*end = '\0';
return start;
}
int parse_line(char *line, char **key, char **value)
{
char *ptr = strchr(line, '=');
if (ptr == NULL)
return -1;
*ptr++ = '\0';
*key = trim(line);
*value = trim(ptr);
return 0;
}
int main()
{
FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t read;
char *key, *value;
fp = fopen("test.txt", "r");
if (fp == NULL) {
printf ("Cannot open file \n");
return -1;
}
while ((read = getline(&line, &len, fp)) != -1) {
if (parse_line(line, &key, &value))
continue;
if (strcmp(key, "NAME") == 0) {
printf("NAME is %s\n", value);
} else if (strcmp(key, "AGE") == 0) {
printf("AGE is %s\n", value);
}
}
free(line);
fclose(fp);
return 0;
}
I'm trying to make a database that holds some datas about teams for now. The problem is that I cannot read the entered datas record by record. I want to explain it with just one example:
insert manunited,manchester,old_trafford,1878,black-rd to teams
insert chelsea,london,stamford_bridge,1905,blue-whte to teams
select colors,team_name,founding_date from teams
select prints on screen the specified information i.e. colors,stadium etc.
insert takes teams information for now.So, According to the select command, output should be followed:
black-rd manunited 1878
blue-whte chelsea 1905
But, I get
black-rd manunited 1878 blue-whte
I've been trying to analyse my error for hours. I cannot find the error(s) and mistake(s).
Thank you for all appreciated answers. By the way, I haven't maden while loop yet to insert or select commands. I'm pondering to find the error(s).
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
char team_name[TEAM_NAME];
char city[TEAM_NAME];
char stadium[STADIUM_NAME];
int founding_date;
char colors[COLOR];
}teams;
int main()
{
char read_command[12];
/* checking insert */
char str1[100],str2[5],str3[18];
FILE *fptr;
teams t;
scanf("%s", read_command);
if(strcmp(read_command,"insert") == 0)
{
scanf("%s %s %s", str1, str2, str3);
//printf("%s\n%s\n%s",str1,str2,str3);
insertfunc(fptr,str1, str2, str3);
}
if(strcmp(read_command,"select") == 0)
{
scanf("%s %s %s", str1, str2, str3);
selectfunc(fptr,str1, str2, str3);
}
return 0;
}
void selectfunc(FILE *fptr,char *str1,char *str2,char *str3)
{
char *buff;
buff = (char*) malloc(strlen(str1) + 1);
strcpy(buff,str1);
char *token;
const char comma[2] = ",";
if(strcmp(str3,"teams") == 0)
{
teams t;
fptr = fopen("teams.bin","rb");
if( fptr == NULL )
{
perror("File cannot be opened.");
exit(1);
}
else
{
while(fread(&t,sizeof(teams),1,fptr) == 1)
{
/* get the first token */
token = strtok(buff, comma);
while( token != NULL )
{
if(strcmp(token,"team_name") == 0)
{
printf(" %s ",t.team_name);
}
else if(strcmp(token,"city") == 0)
{
printf(" %s ",t.city);
}
else if(strcmp(token,"stadium") == 0)
{
printf(" %s ",t.stadium);
}
else if(strcmp(token,"colors") == 0)
{
printf(" %s ",t.colors);
}
else
{
printf(" %d ",t.founding_date);
}
token = strtok(NULL, comma);
}
}
}
fclose(fptr);
}
}
void insertfunc(FILE *fptr,char *str1,char *str2,char *str3)
{
char *buff;
buff = (char*) malloc(strlen(str1) + 1);
strcpy(buff,str1);
const char comma[2] = ",";
/*
if(buff == NULL)
perror("error");
*/
if(strcmp(str3,"teams") == 0)
{
teams t;
int date;
strcpy(t.team_name,strtok(buff, comma));
strcpy(t.city, strtok(NULL, comma));
strcpy(t.stadium, strtok(NULL, comma));
date = atoi(strtok(NULL, comma));
t.founding_date = date;
strcpy(t.colors, strtok(NULL, comma));
fptr = fopen("teams.bin","ab+");
if( fptr == NULL )
{
perror("File cannot be opened.");
exit(1);
}
else
{
fwrite(&t,sizeof(teams),1,fptr);
fclose(fptr);
}
}
free(buff);
}
Working code below.
Apart from changes necessary to get it to build (primarily defining sizes for structure fields), the dump_teams() function is used to log the information from a team record, and the err_exit() function reports errors succinctly. Your error checks are unchanged. My primary objection to perror() is that you typically don't get the key information, such as the file name that wasn't opened, reported. It isn't hard to upgrade err_exit() to report the system error as well as a meaningful message (such as failed to open file "teams.bin": No such file or directory) — exercise for the OP. Those functions are used to validate the information, and to make sure unexpected spellings are detected. Note that the field values in debugging are enclosed in double angle brackets <<…info…>>; this makes it easier to spot various problems, such as leading or trailing spaces, or '\r' characters in input data. The assert() ensures that str2 is used in the two main functions. The select data formatting is made more uniform. There's a single name data_file to hold the data file name.
The key bug fix is in the selectfunc() loop, where the value of str1 is copied into buff afresh for each record.
This is a lazy way of working; it would be better to preparse the string once and then iterate over the data records using the data structure generated by the preparsing. This would matter more if there were millions of records than if there are just 2, of course.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { TEAM_NAME = 20, STADIUM_NAME = 20, COLOR = 20 };
static const char data_file[] = "teams.bin";
typedef struct
{
char team_name[TEAM_NAME];
char city[TEAM_NAME];
char stadium[STADIUM_NAME];
int founding_date;
char colors[COLOR];
} teams;
void insertfunc(char *str1, char *str2, char *str3);
void selectfunc(char *str1, char *str2, char *str3);
void err_exit(const char *fmt, ...);
void dump_teams(FILE *fp, const char *tag, const teams *team);
int main(void)
{
char read_command[12];
char str1[100], str2[5], str3[18];
if (scanf("%s", read_command) != 1)
err_exit("read for command failed");
else if (strcmp(read_command, "insert") == 0)
{
if (scanf("%99s %4s %17s", str1, str2, str3) != 3)
err_exit("read for insert failed");
insertfunc(str1, str2, str3);
}
else if (strcmp(read_command, "select") == 0)
{
if (scanf("%99s %4s %17s", str1, str2, str3) != 3)
err_exit("read for select failed");
selectfunc(str1, str2, str3);
}
else
err_exit("Unrecognized command <<%s>>", read_command);
return 0;
}
void selectfunc(char *str1, char *str2, char *str3)
{
FILE *fptr;
char *buff;
buff = (char*) malloc(strlen(str1) + 1);
char *token;
fprintf(stderr, "select: <<%s>> <<%s> <<%s>>\n", str1, str2, str3);
assert(strcmp(str2, "from") == 0);
const char comma[2] = ",";
if (strcmp(str3, "teams") == 0)
{
teams t;
fptr = fopen(data_file, "rb");
if (fptr == NULL)
{
perror("File cannot be opened.");
exit(1);
}
else
{
while (fread(&t, sizeof(teams), 1, fptr) == 1)
{
dump_teams(stderr, "select", &t);
strcpy(buff, str1);
/* get the first token from command str1 */
token = strtok(buff, comma);
while (token != NULL)
{
fprintf(stderr, "token = <<%s>>\n", token);
if (strcmp(token, "team_name") == 0)
{
printf(" %-20s", t.team_name);
}
else if (strcmp(token, "city") == 0)
{
printf(" %-20s", t.city);
}
else if (strcmp(token, "stadium") == 0)
{
printf(" %-20s", t.stadium);
}
else if (strcmp(token, "colors") == 0)
{
printf(" %-20s", t.colors);
}
else if (strcmp(token, "founding_date") == 0)
{
printf(" %d", t.founding_date);
}
else
err_exit("Unrecognized field name <<%s>>", token);
token = strtok(NULL, comma);
}
putchar('\n');
}
}
fclose(fptr);
}
else
err_exit("Unrecognized data source <<%s>>", str3);
}
void insertfunc(char *str1, char *str2, char *str3)
{
FILE *fptr;
char *buff;
buff = (char*) malloc(strlen(str1) + 1);
strcpy(buff, str1);
fprintf(stderr, "select: <<%s>> <<%s> <<%s>>\n", str1, str2, str3);
assert(strcmp(str2, "to") == 0);
const char comma[2] = ",";
if (strcmp(str3, "teams") == 0)
{
teams t;
int date;
strcpy(t.team_name, strtok(buff, comma));
strcpy(t.city, strtok(NULL, comma));
strcpy(t.stadium, strtok(NULL, comma));
date = atoi(strtok(NULL, comma));
t.founding_date = date;
strcpy(t.colors, strtok(NULL, comma));
dump_teams(stderr, "insert", &t);
fptr = fopen(data_file, "ab+");
if (fptr == NULL)
{
perror("File cannot be opened.");
exit(1);
}
else
{
if (fwrite(&t, sizeof(teams), 1, fptr) != 1)
err_exit("fwrite failed");
fclose(fptr);
}
}
else
err_exit("Unrecognized data destination <<%s>>", str3);
free(buff);
}
void dump_teams(FILE *fp, const char *tag, const teams *team)
{
assert(fp != 0 && tag != 0 && team != 0);
fprintf(fp, "%s\n", tag);
fprintf(fp, "%8s: <<%s>>\n", "Team", team->team_name);
fprintf(fp, "%8s: <<%s>>\n", "City", team->city);
fprintf(fp, "%8s: <<%s>>\n", "Stadium", team->stadium);
fprintf(fp, "%8s: <<%d>>\n", "Founded", team->founding_date);
fprintf(fp, "%8s: <<%s>>\n", "Colours", team->colors);
fflush(fp);
}
#include <stdarg.h>
void err_exit(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
putc('\n', stderr);
exit(EXIT_FAILURE);
}
Sample output
The files cmd1, cmd2 and cmd3 contain the three command lines from the question.
$ ./rw < cmd1
select: <<manunited,manchester,old_trafford,1878,black-red>> <<to> <<teams>>
insert
Team: <<manunited>>
City: <<manchester>>
Stadium: <<old_trafford>>
Founded: <<1878>>
Colours: <<black-red>>
$ ./rw < cmd2
select: <<chelsea,london,stamford_bridge,1905,blue-white>> <<to> <<teams>>
insert
Team: <<chelsea>>
City: <<london>>
Stadium: <<stamford_bridge>>
Founded: <<1905>>
Colours: <<blue-white>>
$ ./rw < cmd3
select: <<colors,team_name,founding_date>> <<from> <<teams>>
select
Team: <<manunited>>
City: <<manchester>>
Stadium: <<old_trafford>>
Founded: <<1878>>
Colours: <<black-red>>
token = <<colors>>
token = <<team_name>>
token = <<founding_date>>
black-red manunited 1878
select
Team: <<chelsea>>
City: <<london>>
Stadium: <<stamford_bridge>>
Founded: <<1905>>
Colours: <<blue-white>>
token = <<colors>>
token = <<team_name>>
token = <<founding_date>>
blue-white chelsea 1905
$ ./rw < cmd3 2>/dev/null
black-red manunited 1878
blue-white chelsea 1905
$
Note that by placing the debug information on standard error, it is easy to separate the debugging information from the normal output, as in the last run.
in my program, I provide a directory which contains text files. Each of the text files contain a few hundred lines in the following format
Username,Password,BloodType,Domain,Number
I then create a thread for each file in the directory which will merge-sort(by number) these lines into the array char* text_lines[6000];
I can't figure out why I'm getting a segmentation fault because I'm getting different output on every run.
Heres my code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
void store_line(char* line);
void* my_merge_sort(void* file);
char** text_lines;
int main(int argc, char* argv[])
{
if(argc != 2)
{
fprintf(stderr, "usage: ./coolsort <directory>\n");
}
else
{
text_lines = malloc(6000 * sizeof(char*));
DIR* the_directory;
int filecount = 0;
struct dirent* directory_files[50];
if((the_directory = opendir(argv[1])) != NULL)
{
//make a list of the files in the directory
while((directory_files[filecount++] = readdir(the_directory))) ;
filecount--;
//<<<DEBUGGING INFO>
int i;
fprintf(stderr,"there are %i files in %s:\n", filecount, argv[1]);
for(i = 0; i < filecount; i++)
{
fprintf(stderr, "%s\n",directory_files[i]->d_name);
}
char cwd[512];
chdir(argv[1]);
getcwd(cwd, sizeof(cwd));
fprintf(stderr, "the CWD is: %s\n", cwd);
//<DEBUGGING INFO>>>
//lets start some threads
pthread_t threads[filecount-2];
int x = 0;
for(i = 0; i < (filecount); i++ )
{
if (!strcmp (directory_files[i]->d_name, "."))
continue;
if (!strcmp (directory_files[i]->d_name, ".."))
continue;
pthread_create(&threads[x++], NULL, my_merge_sort, (void*)directory_files[i]->d_name);
}
//do stuff here
//
}
else
{
fprintf(stderr, "Failed to open directory: %s\n", argv[1]);
}
}
}
void* my_merge_sort(void* file)
{
fprintf(stderr, "We got into the function!\n");
FILE* fp = fopen(file, "r");
char* buffer;
char* line;
char delim[2] = "\n";
int numbytes;
//minimize I/O's by reading the entire file into memory;
fseek(fp, 0L, SEEK_END);
numbytes = ftell(fp);
fseek(fp, 0L, SEEK_SET);
buffer = (char*)calloc(numbytes, sizeof(char));
fread(buffer, sizeof(char), numbytes, fp);
fclose(fp);
//now read the buffer by '\n' delimiters
line = strtok(buffer, delim);
fprintf(stderr, "Heres the while loop\n");
while(line != NULL)
{
store_line(line);
line = strtok(buffer, NULL);
}
free(buffer);
}
void store_line(char* line)
{
//extract the ID.no, which is the fifth comma-seperated-token.
char delim[] = ",";
char* buff;
int id;
int i;
strtok(line, delim);
for(i = 0; i < 3; i++)
{
strtok(line, NULL);
}
buff = strtok(line, NULL);
id = atoi(buff);
//copy the line to text_lines[id]
memcpy(text_lines[id], line, strlen(line));
}
edit: I checked to make sure that it would fit into the initial array, and found that the highest ID is only 3000;
You use of strtok() is wrong:
line = strtok(buffer, NULL);
should be
line = strtok(NULL, delim);
Another mistakes should be fixed similarly.
The elements of text_lines are uninitialized:
text_lines = malloc(6000 * sizeof(char*));
this allocated 6000 pointers to char, but none of these pointers are initialized.