Just to have a look a name in a list, when match, the value is discounted.
I tried to code, but the matching technique is fail. Like I try to find "John", but it match with "John" and "Johnny", whether the expected match is just "John" (case is not sensitive)
Just want to help my mom's store.
What I want is something like:
I have 3 set of flat file (list1.txt, list2.txt, list3.txt). Each file has its name, for example:
John
Rudy
Barrack Obama
John Travolta
List2.txt contained:
Jeddi Sarah
Mute Sand
List3.txt contained:
Greedy Black
Nevada Blue
The program when executed, ask:
Enter name: Greedy Black
Enter price: 1000
If the name is listed in list1.txt, he gets discount price 10%, list2.txt for 20%, and list3.txt for 30%.
example output:
Enter name: Greedy Black
Enter price: 1000
Greedy Black is found in list3.txt, got discount for 10%
price after discount: 900
But if he does not in any list, he gets normal price, which is 1000.
How could I do that in C?
Thank you for the help...
This Works Fine
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_C 111
char *trim(char *str);
int countlines(const char *filename);
char ** names(const char *filename);
int contains(const char* a)
{
int l1 = countlines("list1.txt");
int l2 = countlines("list2.txt");
int l3 = countlines("list3.txt");
char** c1 = names("list1.txt");
char** c2 = names("list2.txt");
char** c3 = names("list3.txt");
for (int i = 0; i < l1; ++i) {
if (strcmp(a,c1[i])== 0 )
return 1;
}
for (int i = 0; i < l2; ++i) {
if (strcmp(a,c2[i])== 0 )
return 2;
}
for (int i = 0; i < l3; ++i) {
if (strcmp(a,c3[i])== 0 )
return 3;
}
for (int j = 0; j < l1; ++j) {
printf("%s\t%s",a,c1[j]);
}
return 0;
}
int main()
{
char * a = (char * ) malloc(MAX_C);
printf("Enter Name:\n");
scanf("%[^\n]",a);
int p;
printf("Enter Price:\n");
scanf("%d",&p);
int c = contains(a);
if(c)
{
printf("Greedy Black is found in list%d.txt, got discount for 10%%\nprice after discount: %f",c,p-p/10.0);
}
else
{
printf("Greedy Black is found in list%d.txt, got discount for 10%%\nprice Without discount: %f",c,p);
}
}
int countlines(const char *filename) {
// count the number of lines in the file called filename
FILE *fp = fopen(filename, "r");
int ch = 0;
int lines = 0;
if (fp == NULL)
return 0;
lines++;
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n')
lines++;
}
fclose(fp);
return lines;
}
char ** names(const char *filename)
{
int line = countlines(filename);
char ** arr = (char **)malloc(line * sizeof(char *));
for (int i=0; i<line; i++)
arr[i] = (char *)malloc(MAX_C * sizeof(char));
FILE * fp = fopen(filename, "r");
if (fp == NULL) {
printf("Could not open file %s", filename);
return NULL;
}
for (int i = 0; i < line; ++i) {
if(fgets(arr[i], MAX_C, fp)!=NULL)
{
trim(arr[i]);
}
}
return arr;
}
char *trim(char *str)
{
size_t len = 0;
char *frontp = str;
char *endp = NULL;
if( str == NULL ) { return NULL; }
if( str[0] == '\0' ) { return str; }
len = strlen(str);
endp = str + len;
/* Move the front and back pointers to address the first non-whitespace
* characters from each end.
*/
while( isspace((unsigned char) *frontp) ) { ++frontp; }
if( endp != frontp )
{
while( isspace((unsigned char) *(--endp)) && endp != frontp ) {}
}
if( frontp != str && endp == frontp )
*str = '\0';
else if( str + len - 1 != endp )
*(endp + 1) = '\0';
/* Shift the string so that it starts at str so that if it's dynamically
* allocated, we can still free it on the returned pointer. Note the reuse
* of endp to mean the front of the string buffer now.
*/
endp = str;
if( frontp != str )
{
while( *frontp ) { *endp++ = *frontp++; }
*endp = '\0';
}
return str;
}
Related
I need some help just starting off my code for this program. This is my first time reading a file in c and I have been stuck starting it off. Essentially, I need to read in two files to calculate Manhattan Distance and output the ID for each file and the closest distance. The files look something like this:
3,2
0, 3.4, 4.3
1, 4.5, 6.1
2, 7.2, 3.9
3,2
0, 5.9, 6.7
1, 8.5, 1.2
2, 9.8, 4.9
My current code only outputs the table and I am trying to find a way to use columns as a way to calculate Manhattan distance. The 3,2 signifies the rows and columns and the 0,1,2 are the IDs. Here is the current code I have found online and modified a bit that I thought may be useful.
#include <stdio.h>
#include <string.h>
int main()
{
FILE* testFile = fopen("Test.txt", "r");
if (!testFile)
printf("Can't open file\n");
else {
char buffer[1024];
int row = 0;
int column = 0;
while (fgets(buffer, 1024, testFile)) {
column = 0;
row++;
if (row == 1)
continue;
// Splitting the data
char* value = strtok(buffer, ", ");
while (value) {
// Column 1
if (column == 0) {
printf("TestID:");
}
// Column 2
if (column == 1) {
printf("\tx1: ");
}
// Column 3
if (column == 2) {
printf("\ty1: ");
}
printf("%s", value);
value = strtok(NULL, ", ");
column++;
}
printf("\n");
}
// Close the file
fclose(testFile);
}
return 0;
}
Here's a basic example demonstrating one method of parsing your input files with strtod and strtoul:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct mat {
int rows;
int columns;
double *data;
};
void
show(const struct mat *A)
{
double *d = A->data;
for( int i = 0; i < A->rows; i += 1 ){
for( int j = 0; j < A->columns; j += 1 ){
printf("%f\t", *d++);
}
putchar('\n');
}
}
/*
* Return nonzero if the first non-whitespace
* character after *e is not v. Terminate search
* at a newline.
*/
int
expect_next(char **e, const char v)
{
char *end = *e;
while( isspace(*end) && *end != '\n' ){
end += 1;
}
*e = end + 1;
return *end != v;
}
int
get_data(struct mat *A, const char *path)
{
unsigned line = 1;
FILE* testFile = fopen(path, "r");
if( testFile == NULL ){
perror(path);
return 0;
}
char buffer[1024];
char *end = buffer;
if( fgets(buffer, sizeof buffer, testFile) == NULL ){
if( ferror(testFile) ){
perror(path);
} else {
goto bad_input;
}
return 0;
}
A->rows = strtoul(buffer, &end, 10);
if( expect_next(&end, ',') ){
goto bad_input;
}
A->columns = strtoul(end, &end, 10);
if( expect_next(&end, '\n') ){
goto bad_input;
}
A->data = malloc(A->rows * A->columns * sizeof *A->data);
if( A->data == NULL ){
perror("malloc");
return 0;
}
double *val = A->data;
unsigned row = 0;
while( NULL != fgets(buffer, sizeof buffer, testFile) ){
line += 1;
unsigned v = strtoul(buffer, &end, 10);
if( v != row ){
goto bad_input;
}
if( expect_next(&end, ',') ){
goto bad_input;
}
unsigned col = 0;
while( col < A->columns && *end ){
*val++ = strtod(end, &end);
if( expect_next(&end, ++col == A->columns ? '\n' : ',') ){
goto bad_input;
}
}
if( col != A->columns ){
goto bad_input;
}
row += 1;
}
if( row != A->rows ){
goto bad_input;
}
if( fclose(testFile) ){
perror(path);
}
return 1;
bad_input:
fprintf(stderr, "%s: Invalid input at line %u, column %u\n", path,
line, (unsigned)(end - buffer));
return 0;
}
int
main(int argc, char ** argv)
{
char *args[] = { NULL, "/dev/stdin", NULL };
if( argc < 2 ){
argv = args;
}
for( argv += 1; *argv; argv += 1 ){
struct mat A;
if( get_data(&A, *argv) ){
show(&A);
}
}
}
I have a dynamic 2D float array and a file with both strings, integers(number of floats in the line) and float numbers.
M = (float**)malloc(num_lines * sizeof(float));
for(int i = 0; i < num_lines; i++){
M[i] = (float*)malloc(num_columns * sizeof(float));
}
Example:
2
John 3 5.5 89.5 30.67 0.00
Mary 4 78.9 67.4 67.3 9.0 0.00
(null)
The number of lines is the one on the file + 1 and the number of columns is the highest integer + 1 (5 in this case) because the 0.00 marks the end of each line.
How do I load only the floats into memory? I've tried different types of loops with fgets and strtok but it doesn't work due to the different types of variables.
The code is like this:
for(int i = 0; i < num_lines; i++){
fgets(buf, 1000, aux);
name = strtok(buf, " ");
col = atoi(strtok(NULL, " "));
for(j = 0; j < num_columns; j++){
M[i][j] = atof(strtok(NULL, " "));
if(M[i][j] == 0.00){
break;
}
}
}
This sort of parsing is a bit of a pain, but is a good exercise to do every now and again. This is relatively easy with scanf, but scanf is not suitable for anything but toys. (It is literally impossible to correctly handle anything robustly, since even a simple "%d" format specifier leads to undefined behavior on certain input.) Unless you are willing to read the file twice to determine the maximum size of a column, you can't preallocate the entire array. Instead of that, I would suggest doing something like:
#include <ctype.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* sample input
2
John 3 5.5 89.5 30.67 0.00
Mary 4 78.9 67.4 67.3 9.0 0.00
*/
FILE * xfopen(const char *, const char *);
void * xmalloc(size_t);
int get_row_count(FILE *in, char **line, size_t *cap, const char *name);
float * parse_line(const char *s, int lc);
int
main(int argc, char **argv)
{
int lc = 0;
char *line = NULL;
size_t cap = 0;
FILE *in = argc > 1 ? xfopen(argv[1], "r") : stdin;
int rows = get_row_count(in, &line, &cap, argv[1]);
float **M = xmalloc(rows * sizeof *M);
for( lc = 0; lc < rows && getline(&line, &cap, in) > 0; lc += 1 ){
M[lc] = parse_line(line, lc + 1);
}
if( lc != rows ){
warnx("invalid input: missing some rows");
}
for( int i = 0; i < lc; i++ ){
float *f = M[i];
for( int j = 0; j < f[0]; j++ ){
printf("%f\t", f[j + 1]);
}
putchar('\n');
}
}
float *
parse_line(const char *s, int lc)
{
/* Skip the name */
char *end;
while( *s && ! isspace(*s) ){
s += 1;
}
int siz = strtol(s, &end, 10);
if( siz <= 0 || ! isspace(*end) ){
errx(EXIT_FAILURE, "Invalid input on line %d", lc);
}
float *f = xmalloc((1 + siz) * sizeof *f);
f[0] = siz;
for( int i = 1; i < siz + 1; i += 1 ){
f[i] = strtof(end, &end);
}
while( isspace(*end) ){
end += 1;
}
if( *end == '\0' || strcmp(end, "0.00\n") ){
errx(EXIT_FAILURE, "Invalid input on line %d", lc);
}
return f;
}
int
get_row_count(FILE *in, char **line, size_t *cap, const char *name)
{
if( getline(line, cap, in) <= 0 ){
if( feof(in) ){
errx(EXIT_FAILURE, "Empty input");
} else {
err(EXIT_FAILURE, "%s", name);
}
}
char *end;
int rows = strtol(*line, &end, 10);
if( rows <= 0 ){
errx(EXIT_FAILURE, "invalid row count: %d", rows);
}
if( *end != '\n' ){
errx(EXIT_FAILURE, "unexpected input on line 1");
}
return rows;
}
FILE *
xfopen(const char *path, const char *mode)
{
FILE *fp = path[0] != '-' || path[1] != '\0' ? fopen(path, mode) :
*mode == 'r' ? stdin : stdout;
if( fp == NULL ){
perror(path);
exit(EXIT_FAILURE);
}
return fp;
}
void *
xmalloc(size_t s)
{
void *rv = malloc(s);
if( rv == NULL ){
perror("malloc");
exit(EXIT_FAILURE);
}
return rv;
}
I'm trying to split a sentence the user inputs to an array of words so I can later manipulate the words separately as strings.
The code is compiling but prints only garbage after the user input.
I tried debugging but don't see the problem. Can someone help me fix it?
#include <stdio.h>
#include <string.h>
int main() {
char str[1000];
int i = 0;
char rev[1000][1000];
int r = 0;
puts("Enter text:");
gets(str);
int k, length = 0;
printf_s("So the words are:\n");
while (str[i] != '\0') {
if (str[i] == ' ') {
k = i - length;
do {
rev[r][k] = (str[k]);
k++;
} while (str[k] != ' ');
printf(" ");
length = (-1);
r++;
} else
if (str[i + 1] == '\0') {
k = i - length;
do {
rev[r][k] = (str[k]);
k++;
} while (str[k] != '\0');
length = 0;
r++;
}
length++;
i++;
}
for (int r = 0; r < 1000; r++)
printf("%s ", rev[r]);
return 0;
}
fix like this
#include <stdio.h>
int main(void) {
char str[1000];
char rev[1000][1000];
puts("Enter text:");
fgets(str, sizeof str, stdin);//Use fgets instead of gets. It has already been abolished.
int r = 0;
int k = 0;
for(int i = 0; str[i] != '\0'; ++i){
if (str[i] == ' ' || str[i] == '\n'){//is delimiter
if(k != 0){
rev[r++][k] = '\0';//add null-terminator and increment rows
k = 0;//reset store position
}
} else {
rev[r][k++] = str[i];
}
}
if(k != 0)//Lastly there was no delimiter
rev[r++][k] = '\0';
puts("So the words are:");
for (int i = 0; i < r; i++){
printf("%s", rev[i]);
if(i < r - 2)
printf(", ");
else if(i == r - 2)
printf(" and ");
}
return 0;
}
Replace you declaration
char rev[1000][1000];
with
char * rev[1000]; // We will need pointers only
int i = 0; // Index to previous array
and all your code after
puts( "Enter text:" );
with this:
fgets( str, 998, stdin ); // Safe way; don't use gets(str)
const char delim[] = ",; "; // Possible delimiters - comma, semicolon, space
char *word;
/* Get the first word */
word = strtok( str, delim );
rev[i++] = word;
/* Get the next words */
while( word != NULL )
{
word = strtok( NULL, delim );
rev[i++] = word;
}
/* Testing */
for (int r = 0; r < i - 1; r++)
printf( "%s\n", rev[r] );
return 0
}
As you can see, all dirty work is done with the strtok() function ("string to tokens") which walks through other and other words ("tokens"), recognizing them as delimited by one or more characters from the string delim.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count_spaces(char *str)
{
if (str == NULL || strlen(str) <= 0)
return (0);
int i = 0, count = 0;
while (str[i])
{
if (str[i] == ' ')
count++;
i++;
}
return (count);
}
int count_char_from_pos(char *str, int pos)
{
if (str == NULL || strlen(str) <= 0)
return 0;
int i = pos, count = 0;
while (str[i] && str[i] != ' ')
{
count++;
i++;
}
return count;
}
char **get_words(char *str)
{
if (str == NULL || strlen(str) <= 0)
{
printf("Bad string inputed");
return NULL;
}
int i = 0, j = 0, k = 0;
char **dest;
if ((dest = malloc(sizeof(char*) * (count_spaces(str) + 1))) == NULL
|| (dest[0] = malloc(sizeof(char) * (count_char_from_pos(str, 0) + 1))) == NULL)
{
printf("Malloc failed\n");
return NULL;
}
while (str[i])
{
if (str[i] == ' ') {
dest[j++][k] = '\0';
if ((dest[j] = malloc(sizeof(char) * (count_char_from_pos(str, i) + 1))) == NULL)
{
printf("Malloc failed\n");
return NULL;
}
k = 0;
}
else {
dest[j][k++] = str[i];
}
i++;
}
dest[j][k] = 0;
dest[j + 1] = NULL;
return dest;
}
int main(void) {
char *line = NULL;
size_t n = 0;
getline(&line, &n, stdin);
printf("%s\n", line);
line[strlen(line) - 1] = 0;
printf("%s\n", line);
char **tab = get_words(line);
int i = 0;
while (tab[i])
{
printf("%s\n", tab[i++]);
}
}
here is a long but fully working example
get the user input
then send it to get_words function. It will get the number of words, the number of characters for each words, allocate everything in memory and writes chars then return it. You get a char ** and prints it just tested it it works
If you wish to split a string into an array of strings, you should consider the strtok function from #include <string.h>. The strtok function will the split the string on the given delimiter(s). For your case, it would the " ".
Using the strtok example from Tutorials Point:
#include <string.h>
#include <stdio.h>
int main(){
char str[80] = "This is - www.tutorialspoint.com - website";//The string you wish to split
const char s[] = "-";//The thing you want it to split from. But there is no need to this.
char *token;//Storing the string
/* get the first token */
token = strtok(str, s);//Split str one time using the delimiter s
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );//Print the string
token = strtok(NULL, s);//Split the string again using the delimiter
}
return(0);
}
I am reading text from an input file in. I have to separate text from scores ie
John Doe 100 95 67 85
jane doe 67 78 99
and then average the numbers. I can separate by the spaces using strtok but how can i tell when i have an integer? i need to split the reading of names and of integers into 2 functions. My code to read it works but i need to stop at the end of each name. I attempted to use numbers converted to strings and using strcmp however it did not work.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void read_reverse_write(FILE * ptr_file, FILE * op);
void write_and_avarage(int * fp, char * op);
//int checker(char *token);
int main(int argc, char** argv) {
FILE *fp;
FILE *op;
//opens quiz and checks and checks to make sure it did
fp = fopen("quiz.txt", "r");
if (fp == NULL) {
printf("Error opening file");
return (-1);
}
//opens op and checks that it did
op = fopen("output.txt", "w");
if (op == NULL) {
printf("Error opening file");
return (-1);
}
// runs read reverse write
read_reverse_write(fp, op);
fclose(fp);
fclose(op);
return (EXIT_SUCCESS);
}
void read_reverse_write(FILE * ptr_file, FILE * op) {
char buf[1000];
char *token;
const char delim[2] = " ";
fgets(buf, 1000, ptr_file);
token = strtok(buf, delim);
while (token != 100) {
fprintf(op, "%s ", token);
token = strtok(NULL, delim);
}
}
/*void write_and_avarage(int * fp, char * op) {
}
int checker(char *token) {
char *arr[102];
char ph[4];
for (int p = 0; p < 100; p++) {
if (p < 10) {
snprintf(ph, 1, "%d", p);
arr[p] = ph;
} else if (p < 99) {
snprintf(ph, 2, "%d", p);
arr[p] = ph;
} else if (p = 100) {
snprintf(ph, 3, "%d", p);
arr[p] = ph;
}
}
for (int z = 0; z < 100; z++) {
if (strcmp(token, arr[z]) == 1) {
return 1;
} else {
z++;
}
return 0;
}
}
*/
You can use the following code to check the whether the string is a number or not.
#include <stdio.h>
#include <string.h>
#define MAX_NUM 9
#define MIN_NUM 0
#define ZERO 0
#define MAX_SIZE 1024
int checkDigit(int num, int len)
{
int divisor = 1, checkVal = 0;
if(len <= 2)
divisor = 10;
else if(len > 2)
{
len = len - 1;
while(len != ZERO)
{
divisor = divisor * 10;
len = len - 1;
}
}
checkVal = num/divisor;
if(checkVal > MIN_NUM && checkVal <= MAX_NUM)
return 1;
else
return 0;
}
void main()
{
char array[MAX_SIZE] = "JOHN DOE 120 DOE HELLO 2323 90909";
char *split_token = NULL;
int status = 2, len = 0, sum = 0, total_digits = 0;
float average = 0;
split_token = strtok(array, " ");
while( split_token != NULL )
{
len = strlen(split_token);
status = checkDigit(atoi(split_token), len);
if (1 == status)
{
sum = sum + atoi(split_token);
total_digits = total_digits + 1;
}
split_token = strtok(NULL, " ");
}
average = (float)sum/total_digits;
printf("Average is : %f\n", average);
}
This code will check whether your string is a number or not and finally calculate the average of all the numbers in the given string.
If you need to read from a file, multiple sets of inputs, use fscanf() and use the complete code logic repeatedly for each line of input.
Hope it helps! Do ask if you need the complete code or any clarification for the code.
I have a program that uses word search. I have a data file which contains the puzzle and the words. What can i implement into my program so that it reads the file and stores the letters present in it as an array?
Example of the data file (it is called testdata):
h e l l o a c d
f g b w o r l d
h a c c v b n a
e q b x n t q q
y e h n c a q r
hello
world
hey
I want to store all the letters in a 2-d array.
Also, I need to store all the words in a 1-dimensional array.
The maximum number of rows of columns or rows that AxA square of letters that is possible in a data file is 25. So, I believe that I should declare an array of that size for the letter and then write them into that array.
I just can't figure out how to read them into that array. There is a space after each letter in the array and no spaces in the words so I think that might be helpful when putting the letters in one array and words in another.
Given your question, and your input, there are a few questions, but in the interest of time, for now, I have made some assumptions about the dimensions of the array, i.e. that it is not necessarily square (as implied by columns or rows that AxA square). The actual data sample disagrees, so I wrote a routine that counts everything as it goes. The letter array is simply an array of arrays, but since it is stored in sequential memory, it just looks like one long array. The strings are each in there own location as well. In any case, this code should illustrate enough to get you on the right track...
#include <ansi_c.h>
#include <stdio.h>
void GetFileContents(char *file, int *nWords, int *lw, int *r, int *c);
void allocMemoryStr(int numStrings, int max);
void allocMemoryLtr(int numStrings, int max);
void freeMemoryStr(int numStrings);
void freeMemoryLtr(int numletters);
#define FILENAME "c:\\dev\\play\\_puzzle.txt"
char **letters;
char **strings;
int main()
{
int longest, cnt, wCount, rows, cols, i;
char line[260];
FILE *fp;
char *buf=0;
GetFileContents(FILENAME, &wCount, &longest, &rows, &cols);
allocMemoryStr(wCount, longest); //for strings
allocMemoryLtr(rows*cols, 1); //for strings
//read file into string arrays
fp = fopen(FILENAME, "r");
cnt=0;
for(i=0;i<rows;i++)
{
fgets(line, 260, fp);
buf = strtok(line, " \n");
while(buf)
{
strcpy(letters[cnt], buf);
buf = strtok(NULL, " \n");
cnt++; //use as accurate count of words.
}
}
cnt=0;
while(fgets(line, 260, fp)) //get remainder of lines into strings
{
//[EDIT]removed fgets()
buf = strtok(line, " \n");
while(buf)
{
strcpy(strings[cnt], buf);
buf = strtok(NULL, " \n");
cnt++; //use as accurate count of words.
}
}
fclose(fp);
freeMemoryStr(wCount);
freeMemoryLtr(rows*cols);
return 0;
}
void GetFileContents(char *file, int *nWords, int *lw, int *r, int *c)
{
char line[260];
FILE *fp;
char *buf=0;
char temp[80];
int wc=0, rc=0, cc=0, ck=0;
fp = fopen(FILENAME, "r");
while(fgets(line, 260, fp))
{
rc++;
buf = strtok(line, " \n");
while(buf)
{
strcpy(temp, buf); // word handler
if(strlen(temp) > 1)
{
wc++;
rc--; //
}
else if(strlen(temp) == 1) //leter handler
{
cc++;
(cc>ck)?(ck=cc):(cc=cc);
}
buf = strtok(NULL, " \n");
}
cc = 0;
}
fclose(fp);
*nWords = wc;
*r = rc;
*c = ck;
}
void allocMemoryStr(int numStrings, int max)
{
int i;
strings = calloc(sizeof(char*)*(numStrings+1), sizeof(char*));
for(i=0;i<numStrings; i++)
{
strings[i] = calloc(sizeof(char)*max + 1, sizeof(char));
}
}
void allocMemoryLtr(int numletters, int max)
{
int i;
letters = calloc(sizeof(char*)*(numletters+1), sizeof(char*));
for(i=0;i<numletters; i++)
{
letters[i] = calloc(sizeof(char)*max + 1, sizeof(char));
}
}
void freeMemoryStr(int numStrings)
{
int i;
for(i=0;i<numStrings; i++)
if(strings[i]) free(strings[i]);
free(strings);
}
void freeMemoryLtr(int numletters)
{
int i;
for(i=0;i<numletters; i++)
if(letters[i]) free(letters[i]);
free(letters);
}
I would parse the file line by line and char by char looking for what i need. In the example (which is untested), i hold three counters to help filling the arrays correctly.
char letters[25][25];
char words[10][25]
int letters_x_pos = 0; // Row counter
int letters_y_pos = 0; // Column counter
int words_pos = 0;
for (int i = 0; i < 25; i++) {
for (int j = 0; j < 25; j++) {
letters[i][j] = '\0';
}
}
const char *line;
while (line = some_read_function()) {
if (!(strlen(line) > 1)) {
continue;
}
if (line[1] == ' ') {
// Line contains letters
const char *letter = line;
while (*letter != '\0') {
if (*letter == ' ' || *letter == '\n' || *letter == '\r') {
continue;
}
else {
letters[letters_x_pos][letters_y_pos++] = *letter;
}
if (letters_y_pos == 25) {
// Maximum reached
break;
}
letter++;
}
// Increment row counter and reset column counter
letters_x_pos++;
letters_y_pos = 0;
if (letters_x_pos == 25) {
// Maximum reached
break;
}
}
else {
// Line contains word
strncpy(words[words_pos++], line, 25);
if (words_pos == 25) {
// Maximum reached
break;
}
}
}