Read print lines from any data function - c

Second, of my assignment, I am new to C program user, but way too behind it. I have to solve it that is due today. I thought in the main (it is really complicated for me to understand the function with file) is supposed taking fscan to read the file and to output with new lines from the file. The file is also included for example too I am using. I know 5 points seem awkward a lot but I am new to C program and have never done with the function part of the C program. I wanted to output with i to count each line to print. I also thought to include the comments help a little bit further info. For the function, I don't know what to write the code for fooen and fgets for the first time.
For example:
Example input/output:
./a.out testfile
1: Bob
2: Tiffany
3: Steve
4: Jim
5: Lucy
...
/* 5 points */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLEN 1000
#define MAX_LINE_LEN 4096
/**
* Complete the function below that takes an array of strings and a integer
* number representing the number of strings in the array and prints them out to
* the screen with a preceding line number (starting with line 1.)
*/
void
printlines (char *a[], int n)
{
}
/**
* Create a main function that opens a file composed of words, one per line
* and saves them to an array of MAXLEN strings that is then printed using
* the above function.
*
* Hints:
* - Use fopen(3) to open a file for reading, the the returned file handle * with the fscanf() function to read the words out of it.
* - You can read a word from a file into a temporary word buffer using the
* fscanf(3) function.
* - You can assume that a word will not be longer than MAXLEN characters.
* - Use the strdup(3) function to make a permanent copy of a string that has
* been read into a buffer.
*
* Usage: "Usage: p7 <file>\n"
*
* Example input/output:
* ./p7 testfile
* 1: Bob
* 2: Tiffany
* 3: Steve
* 4: Jim
* 5: Lucy
* ...
*/
int main (int argv, char *argc[])
{ if (argc < 2)
{
printf ("Usage: p7 <file>\n");
}
char buffer[MAX_LINE_LEN];
/* opening file for reading */
FILE *fp = fopen (argv[1], "r");
if (!fp)
{
perror ("fopen failed"); exit (EXIT_FAILURE);
}
int i = 0;
while ((i <= MAX_LINES) && (fgets (buffer, sizeof (buffer), fp)))
{
printf ("%2i: %s", i, buffer); //i is to count from each lines
i++;
}
fclose (fp);
return (0);
}
View for testfile:
Bob
Tiffany
Steve
Jim
Lucy
Fred
George
Jill
Max
Butters
Randy
Dave
Bubbles

You can do like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLEN 1000
#define MAX_LINE_LEN 4096
void printlines (char *a[], int n)
{
for (int i = 0; i != n; ++i)
printf("%2d: %s\n", i, a[i]);
}
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf ("Usage: p7 <file>\n");
return -1;
}
FILE *fp = fopen (argv[1], "r");
if (!fp)
{
perror ("fopen failed");
exit (EXIT_FAILURE);
}
char* a[MAXLEN];
char buffer[MAX_LINE_LEN];
int i = 0;
while (i < MAXLEN && fscanf(fp, "%s", buffer) == 1)
a[i++] = strdup(buffer);
printlines(a, i);
fclose (fp);
return (0);
}

Related

Reading a text file to extract coordinates in c

i am trying to read a text file and extract the cordinates of 'X' so that i can place then on a map
the text file is
10 20
9 8 X
2 3 P
4 5 G
5 6 X
7 8 X
12 13 X
14 15 X
I tried multiple times but I am unable to extract the relevant data and place it in separate variables to plot
I am quite new to c and am trying to learn things so any help is appreciated
thanks in advance
From my top comments, I suggested an array of point structs.
Here is your code refactored to do that.
I changed the scanf to use %s instead of %c for the point name. It generalizes the point name and [probably] works better with the input line because [I think] the %c would not match up correctly.
It compiles but is untested:
#include <stdio.h>
#include <stdlib.h>
struct point {
int x;
int y;
char name[8];
};
struct point *points;
int count;
int map_row;
int map_col;
void
read_data(const char *file_name)
{
FILE *fp = fopen(file_name, "r");
if (fp == NULL) {
/* if the file opened is empty or has any issues, then show the error */
perror("File Error");
return;
}
/* get the dimensions from the file */
fscanf(fp, "%d %d", &map_row, &map_col);
map_row = map_row + 2;
map_col = map_col + 2;
while (1) {
// enlarge dynamic array
++count;
points = realloc(points,sizeof(*points) * count);
// point to place to store data
struct point *cur = &points[count - 1];
if (fscanf(fp, "%d %d %s", &cur->x, &cur->y, cur->name) != 3)
break;
}
// trim to amount used
--count;
points = realloc(points,sizeof(*points) * count);
fclose(fp);
}
There are a number of way to approach this. Craig has some very good points on the convenience of using a struct to coordinate data of different types. This approach reads with fgets() and parses the data you need with sscanf(). The benefit eliminates the risk of a matching-failure leaving characters unread in your input stream that will corrupt the remainder of your read from the point of matching-failure forward. Reading with fgets() you consume a line of input at a time, and that read is independent of the parsing of values with sscanf().
Putting it altogether and allowing the filename to be provided by the first argument to the program (or reading from stdin by default if no argument is provided), you can do:
#include <stdio.h>
#define MAXC 1024 /* if you need a constand, #define one (or more) */
int main (int argc, char **argv) {
char buf[MAXC]; /* buffer to hold each line */
int map_row, map_col; /* map row/col variables */
/* use filename provided as 1st argument (stdin if none provided) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open");
return 1;
}
/* read/validate first line saving into map_row, map_col */
if (!fgets (buf, MAXC, fp) ||
sscanf (buf, "%d %d", &map_row, &map_col) != 2) {
fputs ("error: EOF or invalid map row/col data.\n", stderr);
return 1;
}
/* loop reading remaining lines, for used as line counter */
for (size_t i = 2; fgets (buf, MAXC, fp); i++) {
char suffix;
int x, y;
/* validate parsing x, y, suffix from buf */
if (sscanf (buf, "%d %d %c", &x, &y, &suffix) != 3) {
fprintf (stderr, "error: invalid format line %zu.\n", i);
continue;
}
if (suffix == 'X') { /* check if line suffix is 'X' */
printf ("%2d %2d %c\n", x, y, suffix);
}
}
if (fp != stdin) { /* close file if not stdin */
fclose (fp);
}
}
(note: this just illustrates the read and isolation of the values from lines with a suffix of 'X'. Data handling, and calculations are left to you)
Example Use/Output
With your data in dat/coordinates.txt you could do:
$ ./bin/readcoordinates dat/coordinates.txt
9 8 X
5 6 X
7 8 X
12 13 X
14 15 X
As Craig indicates, if you need to store your matching data, then an array of struct provides a great solution.

Reading text file into a matrix in C

I have a text file that has 200 x 150 data in it (every number is separated with a space). I am trying to store these numbers into a matrix. My code is this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int i,j, matrix[200][150];
void getMatrix(){
FILE *file;
file = fopen("PICTURE.txt", "r");
char *line, *number;
j = 0;
while(!feof(file)){
i = 0;
fscanf(file, "%s", line);
number = strtok(NULL, " ");
while(number!= NULL){
matrix[i][j] = atoi(number);
}
printf("\n");
j++;
}
}
void printMatrix(){
int a, b;
for(a=0; a<i; a++){
for(b=0; b<j; b++){
printf("%d", matrix[a][b]);
}
printf("\n");
}
}
int main(){
getMatrix();
printMatrix();
}
It prints out literally nothing. I don't understand why. How can I fix my code or do you have any other suggestions for rewriting it?
if you have a file, with 200x150 integer values (either on 200 lines, or all values on one line), then simply looping though the file with fscanf() reading and storing an integer at a time is all that is needed. You must validate each read and provide a way to communicate any failure within a function through the function return (or though a pointer updated within the function)
To begin, do not use MagicNumbers in your code and do not hardcode filenames. Instead, #define the constants you need (or use a global enum) and pass the open FILE* pointer to your read-function as a parameter after having opened (and validated that the file is open for reading) in the calling function. (If the file open fails -- there is no reason to make the read-function call to begin with)
In your case, you only have two needed constants:
#define ROWS 200 /* if you need a constant, #define one (or more) */
#define COLS 150
Do not use global variables unless absolutely necessary (there will be virtually no case where globals are needed when you begin learning C). Passing the matrix (2D array) as a parameter to your read-function, it can be written as:
/* fill m[ROWS][COLS] with values read from fp.
* returns 1 on success, 0 otherwise.
*/
int getmatrix (int (*m)[COLS], FILE *fp)
{
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (fscanf (fp, "%d", &m[row][col]) != 1) {
fprintf (stderr, "error reading m[%d][%d]\n", row, col);
return 0;
}
}
}
return 1;
}
(note: how the return type for the function is int where 1 (true) is returned on success and 0 (false) is returned on failure. Also note that if 200x150 values are unable to be read, failure is returned)
Pass the filename to read from as the 1st argument to your program (that's what int argc, char **argv parameters to main() are for). Alternatively, you can prompt the user and read the filename as input. You can provide a fixed filename as a default value if no filename is entered (stdin is used as the default below), but otherwise do not hardcode filenames. You should not have to recompile your program simply to read from a different filename.
With those improvements made, your main() could be:
int main (int argc, char **argv) {
int matrix[ROWS][COLS] = {{0}}; /* do not use global variables */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading in caller */
perror ("file open failed");
return 1;
}
if (!getmatrix (matrix, fp)) { /* pass array and open FILE*, validate */
return 1;
}
fclose (fp);
prnmatrix (matrix); /* output results */
}
The complete program is:
#include <stdio.h>
#define ROWS 200 /* if you need a constant, #define one (or more) */
#define COLS 150
/* fill m[ROWS][COLS] with values read from fp.
* returns 1 on success, 0 otherwise.
*/
int getmatrix (int (*m)[COLS], FILE *fp)
{
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (fscanf (fp, "%d", &m[row][col]) != 1) {
fprintf (stderr, "error reading m[%d][%d]\n", row, col);
return 0;
}
}
}
return 1;
}
void prnmatrix (int (*m)[COLS])
{
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
printf (col ? " %4d" : "%4d", m[row][col]);
}
putchar ('\n');
}
}
int main (int argc, char **argv) {
int matrix[ROWS][COLS] = {{0}}; /* do not use global variables */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading in caller */
perror ("file open failed");
return 1;
}
if (!getmatrix (matrix, fp)) { /* pass array and open FILE*, validate */
return 1;
}
fclose (fp);
prnmatrix (matrix); /* output results */
}
Example Use/Output
With 200 x 150 random values less than 10000 generated and written to dat/int-200x150.txt, you would run the program as:
$ ./bin/read2darrint dat/int-200x150.txt
9240 5939 3063 5789 7401 7869 4363 3321 7788 1008 7850 ...
2760 5263 5338 6390 8146 155 324 916 4489 3718 1616 ...
...
Where the output is 200 lines of 150 numbers each.
There are many ways to do this. One (better) way would be to loop reading each line of integer values as a string with fgets() and converting each set of ASCII digits into an integer value with strtol(). I say "better" in a sense that strtol() provides far better error reporting in the case of a failed conversion that the simple pass/fail that can be obtained from fscanf().
The read before looping with strtol() would be with fgets() into a sufficiently sized buffer. That way if a matching-failure occurs, the error only impacts that line of data and no offending data is left in your input stream unread (as will occur with a matching-failure and fscanf().
That said, with a properly formatted space-separated file full of data, there is nothing wrong with using fscanf() directly, just be aware there are more robust ways to do the read and conversion.
To use strtol(), to work through each line of values, you simply use a pointer to the beginning of each set of digits calling strtol() which then updates the endptr to one past the last digit converted allowing you to work your way though each number by updating the pointer (nptr) to endptr after each validated conversion. See man 3 strtol. You could updated the code above with:
...
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
...
#define MAXC 2048 /* (150 int + space) max of 1800 chars per-line */
and finally change your function to use strtol(), e.g.
/* fill m[ROWS][COLS] with values read from fp.
* returns 1 on success, 0 otherwise.
*/
int getmatrix (int (*m)[COLS], FILE *fp)
{
char buf[MAXC]; /* buffer to hold each line */
for (int row = 0; row < ROWS; row++) {
char *nptr = buf, *endptr = nptr; /* nptr and endptr for strtol */
if (!fgets (buf, MAXC, fp)) { /* read line of input */
fprintf (stderr, "error: failed to read line %d\n", row);
return 0;
}
for (int col = 0; col < COLS; col++) {
errno = 0; /* reset errno */
long tmp = strtol (nptr, &endptr, 10); /* convert w/strtol */
if (nptr == endptr) { /* no ASCII digits coverted to a number */
fputs ("error: no digits converted.\n", stderr);
return 0;
}
else if (errno) { /* error in converstion, under/overflow */
fputs ("error: under/overflow occurred in conversion.\n", stderr);
return 0;
}
/* conversion outside range of int */
else if (tmp < INT_MIN || INT_MAX < tmp) {
fputs ("error: conversion out of range of integer.\n", stderr);
return 0;
}
m[row][col] = tmp; /* assign tmp to m[row][col] */
nptr = endptr; /* update nptr to endptr */
}
}
return 1;
}
If an error occurs, you will know exactly what caused the failure. Look things over and let me know if you have further questions.
Many problems:
Never use while(!feof(file)){. Instead check the return value of fscanf(file, ...)
Do not use "%s" with out a width limit.
Do not use pass line to a function without initializing/assigning it first.
i never incremented.
fclose(file) when done.
Check success of fopen(...);
GTG, maybe more later.

C - Can't store file into an array of strings (based off line break)

I'm pretty new to C and someone "challenged" me to try and create a sorting program using C. I come from languages that are higher-level where doing something like this is easier, but I guess the lower-level intricacies are way over my head. I haven't implemented the sorting yet, because I've ran across an obstacle (just one of many) along the way.
Anyways, here is the code I have so far:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *unsortedFile; /* prepare file variable */
char lineBuffer[100]; /* prepare variable for each line */
char *listOfLines[100]; /* prepare line array variable to be sorted */
int n = 0;
int i;
if (argc == 2) /* if a file has been given */
{
unsortedFile = fopen(argv[1], "r"); /* open it readonly */
if (unsortedFile == NULL) /* if it couldn't open */
{
printf("Couldn't open the file %s\n", argv[1]);
printf("Does it exist?\n");
return -1; /* stop the program here, return non-zero for error */
}
printf("original file:\n\n");
while (fgets(lineBuffer, sizeof(lineBuffer), unsortedFile))
{
printf("%s", lineBuffer);
listOfLines[n] = lineBuffer; /* store line buffer to the array */
n = ++n; /* increase n for the next array element */
}
printf("\nLines to be sorted: %d\n", n);
for (i = 0; i < n; i++)
{
printf("%s", listOfLines[i]);
}
} else /* if no or too many args provided */
{
printf("\nArgument error - you either didn't supply a filename\n");
printf("or didn't surround the filename in quotes if it has spaces\n\n");
return -1; /* return non-zero for error */
}
}
At this point, you're probably busy vomiting over the messiest spaghetti code you've ever seen... but anyways, the issue occurs with that while statement, I guess. The original file prints to the console fine, but I don't think each line is being stored to listOfLines.
Here is what's in file.txt, the file I am supplying as an argument to the program:
zebra
red
abacus
banana
And here is the output of the program:
dustin#DESKTOP-033UL9B:/mnt/c/Users/Dustin/projects/c/sort$ ./sort file.txt
original file:
zebra
red
abacus
banana
Lines to be sorted: 4
banana
banana
banana
banana
dustin#DESKTOP-033UL9B:/mnt/c/Users/Dustin/projects/c/sort$
Looks like the last line of the file is the only one being stored to listOfLines? What could cause this behavior?
Thanks in advance!
listOfLines is an array of pointers. All those pointers are set to point to lineBuffer:
listOfLines[n] = lineBuffer;
And lineBuffer is repeatedly overwritten by lines from the file. The last line is banana, which is the final value of lineBuffer.
Your code then prints the values in listOfLines, which are all pointers to lineBuffer.
This line is very wrong, by the way (it has undefined behavior):
n = ++n;
If you want to increment n, that's either
n = n + 1;
or
++n;
Basically, don't modify the same variable twice within the same statement.
You need an array of char arrays (not array of pointers)
Switched:
char *lineOfLines[100]; // array of pointers
char listOfLines[100][100]; // array of char arrays
Then use strcpy.
Switched:
listOfLines[n] = lineBuffer;
strcpy(listOfLines[n], lineBuffer);
Working:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *unsortedFile; /* prepare file variable */
char lineBuffer[100]; /* prepare variable for each line */
char listOfLines[100][100]; /* prepare line array variable to be sorted */
int n = 0;
int i;
if (argc == 2) /* if a file has been given */
{
unsortedFile = fopen(argv[1], "r"); /* open it readonly */
if (unsortedFile == NULL) /* if it couldn't open */
{
printf("Couldn't open the file %s\n", argv[1]);
printf("Does it exist?\n");
return -1; /* stop the program here, return non-zero for error */
}
printf("original file:\n\n");
while (fgets(lineBuffer, sizeof(lineBuffer), unsortedFile))
{
printf("%s", lineBuffer);
strcpy(listOfLines[n], lineBuffer); /* store line buffer to the array */
n = n + 1; /* increase n for the next array element */
}
printf("\nLines to be sorted: %d\n", n);
for (i = 0; i < n; i++)
{
printf("%s", listOfLines[i]);
}
} else /* if no or too many args provided */
{
printf("\nArgument error - you either didn't supply a filename\n");
printf("or didn't surround the filename in quotes if it has spaces\n\n");
return -1; /* return non-zero for error */
}
}

For every possible pair of two unique words in the file, print out the count of occurrences of that pair [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
this code works for single word counts and it differentiate between words with punctuation words with upper lower case. Is there an easy way around to make this code work for pairs as well instead of single words? like I need to print the occurrence of every pair of words in a text file.
Your help is much appreciated,
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE* f = fopen (argv[1], "r");
char buffer[10000];
if (argc != 2)
{
fprintf(stderr, "Usage: %s file\n", argv[0]);
}
fclose(f);
snprintf(buffer, sizeof(buffer), "tr -cs '[:punct:][a-z][A-Z]' '[\\n*]' < %s |"
" sort | uniq -c | sort -n", argv[1]);
return(system(buffer));
}
Example input
The Cat Sat On The Mat
Output
(The Cat, The Sat, The On, The The, The Mat, Cat The, Cat Sat, Cat On, for 30 pairs)
It seems inconceivable that the purpose of your assignment determining the frequency of word-pairs in a file would be to have you wrap a piped-string of shell utilities in a system call. What does that possibly teach you about C? That a system function exists that allows shell access? Well, it does, and you can, lesson done, nothing learned.
It seems far more likely that the intent was for you to understand the use of structures to hold collections of related data in a single object, or at the minimum array or pointer indexing to check for pairs in adjacent words within a file. Of the 2 normal approaches, use of a struct, or index arithmetic, the use of a struct is far more beneficial. Something simple to hold a pair of words and the frequency that pair is seen is all you need. e.g.:
enum { MAXC = 32, MAXP = 100 };
typedef struct {
char w1[MAXC];
char w2[MAXC];
size_t freq;
} wordpair;
(note, the enum simply defines the constants MAXC (32) and MAXP (100) for maximum characters per-word, and maximum pairs to record. You could use two #define statements to the same end)
You can declare an array of the wordpair struct which will hold a pair or words w1 and w2 and how many time that pair is seen in freq. The array of struct can be treated like any other array, sorted, etc..
To analyze the file, you simply need to read the first two words into the first struct, save a pointer to the second word, and then read each remaining word that remains in the file comparing whether the pair formed by the pointer and the new word read already exists (if so simply update the number of times seen), and if it doesn't exist, add a new pair updating the pointer to point to the new word read, and repeat.
Below is a short example that will check the pair occurrence for the words in all filenames given as arguments on the command line (e.g. ./progname file1 file2 ...). If no file is given, the code will read from stdin by default.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXC = 32, MAXP = 100 };
typedef struct {
char w1[MAXC];
char w2[MAXC];
size_t freq;
} wordpair;
size_t get_pair_freq (wordpair *words, FILE *fp);
int compare (const void *a, const void *b);
int main (int argc, char **argv) {
/* initialize variables & open file or stdin for seening */
wordpair words[MAXP] = {{"", "", 0}};
size_t i, idx = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
/* read from file given, or from stdin (default) */
idx = get_pair_freq (words, stdin);
/* read each remaining file given on command line */
for (i = 2; i < (size_t)argc; i++)
{ if (fp && fp != stdin) { fclose (fp); fp = NULL; }
/* open file for reading */
if (!(fp = fopen (argv[i], "r"))) {
fprintf (stderr, "error: file open failed '%s'.\n",
argv[i]);
continue;
}
/* check 'idx' against MAXP */
if ((idx += get_pair_freq (words, fp)) == MAXP)
break;
}
if (fp && fp != stdin) fclose (fp);
/* sort words alphabetically */
qsort (words, idx, sizeof *words, compare);
/* output the frequency of word pairs */
printf ("\nthe occurrence of words pairs are:\n\n");
for (i = 0; i < idx; i++) {
char pair[MAXC * 2] = "";
sprintf (pair, "%s:%s", words[i].w1, words[i].w2);
printf (" %-32s : %zu\n", pair, words[i].freq);
}
return 0;
}
size_t get_pair_freq (wordpair *pairs, FILE *fp)
{
char w1[MAXC] = "", w2[MAXC] = "";
char *fmt1 = " %32[^ ,.\t\n]%*c";
char *fmt2 = " %32[^ ,.\t\n]%*[^A-Za-z0-9]%32[^ ,.\t\n]%*c";
char *w1p;
int nw = 0;
size_t i, idx = 0;
/* read 1st 2 words into pair, update index 'idx' */
if (idx == 0) {
if ((nw = fscanf (fp, fmt2, w1, w2)) == 2) {
strcpy (pairs[idx].w1, w1);
strcpy (pairs[idx].w2, w2);
pairs[idx].freq++;
w1p = pairs[idx].w2; /* save pointer to w2 for next w1 */
idx++;
}
else {
if (!nw) fprintf (stderr, "error: file read error.\n");
return idx;
}
}
/* read each word in file into w2 */
while (fscanf (fp, fmt1, w2) == 1) {
/* check against all pairs in struct */
for (i = 0; i < idx; i++) {
/* check if pair already exists */
if (strcmp (pairs[i].w1, w1p) == 0 &&
strcmp (pairs[i].w2, w2) == 0) {
pairs[i].freq++; /* update frequency for pair */
goto skipdup; /* skip adding duplicate pair */
}
} /* add new pair, update pairs[*idx].freq */
strcpy (pairs[idx].w1, w1p);
strcpy (pairs[idx].w2, w2);
pairs[idx].freq++;
w1p = pairs[idx].w2;
idx++;
skipdup:
if (idx == MAXP) { /* check 'idx' against MAXP */
fprintf (stderr, "warning: MAXP words exceeded.\n");
break;
}
}
return idx;
}
/* qsort compare funciton */
int compare (const void *a, const void *b)
{
return (strcmp (((wordpair *)a)->w1, ((wordpair *)b)->w1));
}
Use/Output
Given your example of "Hi how are you are you.", it produces the desired results (in sorted order according to your LOCALE).
$ echo "Hi how are you are you." | ./bin/file_word_pairs
the occurrence of words pairs are:
Hi:how : 1
are:you : 2
how:are : 1
you:are : 1
(there is no requirement that you sort the results, but it makes lookup/confirmation a lot easier with longer files)
Removing qsort
$ echo "Hi how are you are you." | ./bin/file_word_pairs
the occurrence of words pairs are:
Hi:how : 1
how:are : 1
are:you : 2
you:are : 1
While you are free to attempt to use your system version, why not take the time to learn how to approach the problem in C. If you want to learn how to do it through a system call, take a Linux course, as doing it in that manner has very little to do with C.
Look it over, lookup the functions that are new to you in the man pages and then ask about anything you don't understand thereafter.

Read a txt file, and memorize into int or long in C

I'm not a C genius. So..first of all sorry for my stupid question.
I have a .txt file or .dta (whatever) and I want to read it in C.
I would like to take the numbers of the txt, formatted as two columns and x rows, and memorize all the data into a matrix (or vector).
Up to know I m using this code:
/*
** File FILE_3.C
**
** Illustrates how to read from a file.
**
** The file is opened for reading. Each line is successively fetched
** using fgets command. The string is then converted to a long integer.
**
** Note that fgets returns NULL when there are no more lines in the file.
**
** In this example file ELAPSED.DTA consists of various elapsed times in
** seconds. This may have been the result of logging the time of events
** using an elapsed time counter which increments each second from the
** time the data logger was placed in service.
**
** Typical data in elapsed.dta might be;
**
** 653 75
** 142 90
** 104 10
** 604 10
** 124 12
**
*/
#include <stdio.h> /* required for file operations */
FILE *fr; /* declare the file pointer */
main()
{
int n;
long elapsed_seconds;
char line[80];
fr = fopen ("elapsed.txt", "rt"); /* open the file for reading */
/* elapsed.dta is the name of the file */
/* "rt" means open the file for reading text */
while(fgets(line, 80, fr) != NULL)
{
sscanf (line, "%ld", &elapsed_seconds);
/* convert the string to a long int */
printf ("%ld\n", elapsed_seconds);
}
fclose(fr); /* close the file prior to exiting the routine */
} /*of main*/
Can you help me?
Thanks for your answer
You can use fscanf rather then fgets and sscanf.
And look at the scanf format carefuly (http://en.wikipedia.org/wiki/Scanf_format_string)
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * fr;
int row = 0;
int i;
int arr[8][2]; // max 8 rows!
fr = fopen ("file.txt", "r");
if ( fr == NULL )
{
printf( "Can't open file\n" );
exit(0);
}
while( fscanf (fr, "%d %d\n", &arr[row][0], &arr[row][1]) == 2 )
row ++;
for (i = 0; i < row; i++)
printf( "(%d) (%d)\n", arr[i][0], arr[i][1] );
fclose(fr);
}
You have to allocate an array to hold your elapsed_second values.
long * seconds_array;
seconds_array = calloc( SIZEOFARRAY, sizeof(long));
In c an array is more or less the same as a pointer.
Like in this example from http://www.cplusplus.com/reference/cstdlib/calloc/
In the example pData is given a fixed size and this means that you either must know in advance how many numbers you have or you must keep track on how many numbers you've entered and allocate a new pData array when you run out of space.
In the example the numbers are taken from stdin but the principles are the same. when reading from a file. The for loop should probably be more like a while loop in your case.
/* calloc example */
#include <stdio.h> /* printf, scanf, NULL */
#include <stdlib.h> /* calloc, exit, free */
int main ()
{
int i,n;
int * pData;
printf ("Amount of numbers to be entered: ");
scanf ("%d",&i);
pData = (int*) calloc (i,sizeof(int));
if (pData==NULL) exit (1);
for (n=0;n<i;n++)
{
printf ("Enter number #%d: ",n+1);
scanf ("%d",&pData[n]);
}
printf ("You have entered: ");
for (n=0;n<i;n++) printf ("%d ",pData[n]);
free (pData);
return 0;
}
PS dont forget to call free on your array when you are done with it.
http://www.cplusplus.com/reference/cstdlib/free/

Resources